/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> public virtual ExprNode MakeNP2(int opecode, ExprNode node1, ExprNode node2) { // 定数の最适化 if (node1 != null && node1.GetOpecode() == Token.T_CONSTVAL && node2 != null && node2 .GetOpecode() == Token.T_CONSTVAL) { switch (opecode) { case Token.T_COMMA: { return MakeConstValNode(node2.GetValue()); } case Token.T_LOGICALOR: { return MakeConstValNode(node1.GetValue().LogicOr(node2.GetValue())); } case Token.T_LOGICALAND: { return MakeConstValNode(node1.GetValue().LogicAnd(node2.GetValue())); } case Token.T_VERTLINE: { return MakeConstValNode(node1.GetValue().BitOr(node2.GetValue())); } case Token.T_CHEVRON: { return MakeConstValNode(node1.GetValue().BitXor(node2.GetValue())); } case Token.T_AMPERSAND: { return MakeConstValNode(node1.GetValue().BitAnd(node2.GetValue())); } case Token.T_NOTEQUAL: { return MakeConstValNode(node1.GetValue().NotEqual(node2.GetValue())); } case Token.T_EQUALEQUAL: { return MakeConstValNode(node1.GetValue().EqualEqual(node2.GetValue())); } case Token.T_DISCNOTEQUAL: { return MakeConstValNode(node1.GetValue().DiscNotEqual(node2.GetValue())); } case Token.T_DISCEQUAL: { return MakeConstValNode(node1.GetValue().DiscernCompare(node2.GetValue())); } case Token.T_LT: { return MakeConstValNode(node1.GetValue().Lt(node2.GetValue())); } case Token.T_GT: { return MakeConstValNode(node1.GetValue().Gt(node2.GetValue())); } case Token.T_LTOREQUAL: { return MakeConstValNode(node1.GetValue().LtOrEqual(node2.GetValue())); } case Token.T_GTOREQUAL: { return MakeConstValNode(node1.GetValue().GtOrEqual(node2.GetValue())); } case Token.T_RARITHSHIFT: { return MakeConstValNode(node1.GetValue().RightShift(node2.GetValue())); } case Token.T_LARITHSHIFT: { return MakeConstValNode(node1.GetValue().LeftShift(node2.GetValue())); } case Token.T_RBITSHIFT: { return MakeConstValNode(node1.GetValue().RightBitShift(node2.GetValue())); } case Token.T_PLUS: { return MakeConstValNode(node1.GetValue().Add(node2.GetValue())); } case Token.T_MINUS: { return MakeConstValNode(node1.GetValue().Subtract(node2.GetValue())); } case Token.T_PERCENT: { return MakeConstValNode(node1.GetValue().Residue(node2.GetValue())); } case Token.T_SLASH: { return MakeConstValNode(node1.GetValue().Divide(node2.GetValue())); } case Token.T_BACKSLASH: { return MakeConstValNode(node1.GetValue().Idiv(node2.GetValue())); } case Token.T_ASTERISK: { return MakeConstValNode(node1.GetValue().Multiply(node2.GetValue())); } } } ExprNode node = new ExprNode(); mNodeToDeleteVector.AddItem(node); node.SetOpecode(opecode); node.SetPosition(GetLexPos()); node.Add(node1); node.Add(node2); return node; }
/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> private int GenNodeCode(IntWrapper frame, ExprNode node, int restype, int reqresaddr , InterCodeGenerator.SubParam param) { if (node == null) { return 0; } int resaddr; int node_pos = (node != null ? node.GetPosition() : -1); switch (node.GetOpecode()) { case Token.T_CONSTVAL: { // constant value if (param.mSubType != stNone) { ErrorMsg(Error.CannotModifyLHS); } if ((restype & RT_NEEDED) == 0) { return 0; } int dp = PutData(node.GetValue()); //putCode( VM_CONST, node_pos ); //putCode( frame.value, node_pos ); //putCode( dp, node_pos ); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_CONST); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(dp); mCodeAreaPos++; int ret = frame.value; frame.value++; return ret; } case Token.T_IF: { // 'if' if ((restype & RT_NEEDED) != 0) { ErrorMsg(Error.CannotGetResult); } int resaddr1 = GenNodeCode(frame, node.GetNode(1), RT_NEEDED | RT_CFLAG, 0, new InterCodeGenerator.SubParam ()); bool inv = false; if (!(resaddr1 == GNC_CFLAG || resaddr1 == GNC_CFLAG_I)) { //putCode( VM_TT, node_pos ); //putCode( resaddr1, node_pos ); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_TT); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr1); mCodeAreaPos++; } else { if (resaddr1 == GNC_CFLAG_I) { inv = true; } } int addr = mCodeAreaPos; //addJumpList(); mJumpList.Add(mCodeAreaPos); //putCode( inv ? VM_JF : VM_JNF, node_pos ); //putCode( 0, node_pos ); // * if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(inv ? VM_JF : VM_JNF); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; GenNodeCode(frame, node.GetNode(0), 0, 0, param); mCodeArea[addr + 1] = (short)(mCodeAreaPos - addr); // patch "*" return 0; } case Token.T_INCONTEXTOF: { // 'incontextof' if ((restype & RT_NEEDED) == 0) { return 0; } int resaddr1; int resaddr2; resaddr1 = GenNodeCode(frame, node.GetNode(0), RT_NEEDED, 0, param); resaddr2 = GenNodeCode(frame, node.GetNode(1), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); if (resaddr1 <= 0) { //putCode( VM_CP, node_pos ); //putCode( frame.value, node_pos ); //putCode( resaddr1, node_pos ); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_CP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr1); mCodeAreaPos++; resaddr1 = frame.value; frame.value++; } //putCode( VM_CHGTHIS, node_pos ); //putCode( resaddr1, node_pos ); //putCode( resaddr2, node_pos ); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_CHGTHIS); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr1); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr2); mCodeAreaPos++; return resaddr1; } case Token.T_COMMA: { // ',' GenNodeCode(frame, node.GetNode(0), 0, 0, new InterCodeGenerator.SubParam()); return GenNodeCode(frame, node.GetNode(1), restype, reqresaddr, param); } case Token.T_SWAP: { // '<->' if ((restype & RT_NEEDED) != 0) { ErrorMsg(Error.CannotGetResult); } if (param.mSubType != 0) { ErrorMsg(Error.CannotModifyLHS); } int resaddr1 = GenNodeCode(frame, node.GetNode(0), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); if (resaddr1 <= 0) { //putCode( VM_CP, node_pos ); //putCode( frame.value, node_pos ); //putCode( resaddr1, node_pos ); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_CP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr1); mCodeAreaPos++; resaddr1 = frame.value; frame.value++; } int resaddr2 = GenNodeCode(frame, node.GetNode(1), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); InterCodeGenerator.SubParam param2 = new InterCodeGenerator.SubParam(); param2.mSubType = stEqual; param2.mSubAddress = resaddr2; GenNodeCode(frame, node.GetNode(0), 0, 0, param2); param2.mSubType = stEqual; param2.mSubAddress = resaddr1; GenNodeCode(frame, node.GetNode(1), 0, 0, param2); return 0; } case Token.T_EQUAL: { // '=' if (param.mSubType != 0) { ErrorMsg(Error.CannotModifyLHS); } if ((restype & RT_CFLAG) != 0) { OutputWarning(Error.SubstitutionInBooleanContext, node_pos); } resaddr = GenNodeCode(frame, node.GetNode(1), RT_NEEDED, 0, param); InterCodeGenerator.SubParam param2 = new InterCodeGenerator.SubParam(); param2.mSubType = stEqual; param2.mSubAddress = resaddr; GenNodeCode(frame, node.GetNode(0), 0, 0, param2); return resaddr; } case Token.T_AMPERSANDEQUAL: case Token.T_VERTLINEEQUAL: case Token.T_CHEVRONEQUAL: case Token.T_MINUSEQUAL: case Token.T_PLUSEQUAL: case Token.T_PERCENTEQUAL: case Token.T_SLASHEQUAL: case Token.T_BACKSLASHEQUAL: case Token.T_ASTERISKEQUAL: case Token.T_LOGICALOREQUAL: case Token.T_LOGICALANDEQUAL: case Token.T_RARITHSHIFTEQUAL: case Token.T_LARITHSHIFTEQUAL: case Token.T_RBITSHIFTEQUAL: { // '&=' operator // '|=' operator // '^=' operator // ^-=' operator // '+=' operator // '%=' operator // '/=' operator // '\=' operator // '*=' operator // '||=' operator // '&&=' operator // '>>=' operator // '<<=' operator // '>>>=' operator if (param.mSubType != 0) { ErrorMsg(Error.CannotModifyLHS); } resaddr = GenNodeCode(frame, node.GetNode(1), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); InterCodeGenerator.SubParam param2 = new InterCodeGenerator.SubParam(); switch (node.GetOpecode()) { case Token.T_AMPERSANDEQUAL: { // this may be sucking... param2.mSubType = stBitAND; break; } case Token.T_VERTLINEEQUAL: { param2.mSubType = stBitOR; break; } case Token.T_CHEVRONEQUAL: { param2.mSubType = stBitXOR; break; } case Token.T_MINUSEQUAL: { param2.mSubType = stSub; break; } case Token.T_PLUSEQUAL: { param2.mSubType = stAdd; break; } case Token.T_PERCENTEQUAL: { param2.mSubType = stMod; break; } case Token.T_SLASHEQUAL: { param2.mSubType = stDiv; break; } case Token.T_BACKSLASHEQUAL: { param2.mSubType = stIDiv; break; } case Token.T_ASTERISKEQUAL: { param2.mSubType = stMul; break; } case Token.T_LOGICALOREQUAL: { param2.mSubType = stLogOR; break; } case Token.T_LOGICALANDEQUAL: { param2.mSubType = stLogAND; break; } case Token.T_RARITHSHIFTEQUAL: { param2.mSubType = stSAR; break; } case Token.T_LARITHSHIFTEQUAL: { param2.mSubType = stSAL; break; } case Token.T_RBITSHIFTEQUAL: { param2.mSubType = stSR; break; } } param2.mSubAddress = resaddr; return GenNodeCode(frame, node.GetNode(0), restype, reqresaddr, param2); } case Token.T_QUESTION: { // '?' ':' operator // three-term operator ( ? : ) int resaddr1; int resaddr2; int frame1; int frame2; resaddr = GenNodeCode(frame, node.GetNode(0), RT_NEEDED | RT_CFLAG, 0, new InterCodeGenerator.SubParam ()); bool inv = false; if (!(resaddr == GNC_CFLAG || resaddr == GNC_CFLAG_I)) { //putCode( VM_TT, node_pos ); //putCode( resaddr, node_pos ); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_TT); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; } else { if (resaddr == GNC_CFLAG_I) { inv = true; } } int cur_frame = frame.value; int addr1 = mCodeAreaPos; //addJumpList(); mJumpList.Add(mCodeAreaPos); //putCode( inv ? VM_JF : VM_JNF, node_pos ); //putCode( 0, node_pos ); // patch if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(inv ? VM_JF : VM_JNF); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; resaddr1 = GenNodeCode(frame, node.GetNode(1), restype, reqresaddr, param); if ((restype & RT_CFLAG) != 0) { if (!(resaddr1 == GNC_CFLAG || resaddr1 == GNC_CFLAG_I)) { //putCode( VM_TT, node_pos ); //putCode( resaddr1 ); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_TT); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr1); mCodeAreaPos++; } else { if (resaddr1 == GNC_CFLAG_I) { //putCode( VM_NF, node_pos ); // invert flag if ((mCodeAreaPos) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_NF); mCodeAreaPos++; } } } else { if ((restype & RT_NEEDED) != 0 && !(resaddr1 == GNC_CFLAG || resaddr1 == GNC_CFLAG_I ) && resaddr1 <= 0) { //putCode( VM_CP, node_pos ); //putCode( frame.value, node_pos ); //putCode( resaddr1, node_pos ); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_CP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr1); mCodeAreaPos++; resaddr1 = frame.value; frame.value++; } } frame1 = frame.value; int addr2 = mCodeAreaPos; //addJumpList(); mJumpList.Add(mCodeAreaPos); //putCode( VM_JMP, node_pos ); //putCode( 0, node_pos ); // patch if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_JMP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; mCodeArea[addr1 + 1] = (short)(mCodeAreaPos - addr1); // patch frame.value = cur_frame; resaddr2 = GenNodeCode(frame, node.GetNode(2), restype, reqresaddr, param); if ((restype & RT_CFLAG) != 0) { // condition flag required if (!(resaddr2 == GNC_CFLAG || resaddr2 == GNC_CFLAG_I)) { //putCode( VM_TT, node_pos ); //putCode( resaddr2 ); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_TT); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr2); mCodeAreaPos++; } else { if (resaddr2 == GNC_CFLAG_I) { //putCode( VM_NF, node_pos ); // invert flag if ((mCodeAreaPos) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_NF); mCodeAreaPos++; } } } else { if ((restype & RT_NEEDED) != 0 && !(resaddr1 == GNC_CFLAG || resaddr1 == GNC_CFLAG_I ) && resaddr1 != resaddr2) { //putCode( VM_CP, node_pos ); //putCode( resaddr1, node_pos ); //putCode( resaddr2, node_pos ); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_CP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr1); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr2); mCodeAreaPos++; frame.value++; } } frame2 = frame.value; mCodeArea[addr2 + 1] = (short)(mCodeAreaPos - addr2); // patch frame.value = frame2 < frame1 ? frame1 : frame2; return (restype & RT_CFLAG) != 0 ? GNC_CFLAG : resaddr1; } case Token.T_LOGICALOR: case Token.T_LOGICALAND: { // '||' // '&&' // "logical or" and "locical and" // these process with th "shortcut" : // OR : does not evaluate right when left results true // AND : does not evaluate right when left results false if (param.mSubType != 0) { ErrorMsg(Error.CannotModifyLHS); } int resaddr1; int resaddr2; resaddr1 = GenNodeCode(frame, node.GetNode(0), RT_NEEDED | RT_CFLAG, 0, new InterCodeGenerator.SubParam ()); bool inv = false; if (!(resaddr1 == GNC_CFLAG || resaddr1 == GNC_CFLAG_I)) { //putCode( VM_TT, node_pos ); //putCode( resaddr1, node_pos ); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_TT); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr1); mCodeAreaPos++; } if (resaddr1 == GNC_CFLAG_I) { inv = true; } int addr1 = mCodeAreaPos; //addJumpList(); mJumpList.Add(mCodeAreaPos); //putCode( node.getOpecode() == Token.T_LOGICALOR ? (inv?VM_JNF:VM_JF) : (inv?VM_JF:VM_JNF), node_pos ); //putCode( 0, node_pos ); // *A if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(node.GetOpecode() == Token.T_LOGICALOR ? (inv ? VM_JNF : VM_JF) : (inv ? VM_JF : VM_JNF)); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; resaddr2 = GenNodeCode(frame, node.GetNode(1), RT_NEEDED | RT_CFLAG, 0, new InterCodeGenerator.SubParam ()); if (!(resaddr2 == GNC_CFLAG || resaddr2 == GNC_CFLAG_I)) { //putCode( inv ? VM_TF : VM_TT, node_pos ); //putCode( resaddr2, node_pos ); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(inv ? VM_TF : VM_TT); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr2); mCodeAreaPos++; } else { if ((inv != false) != (resaddr2 == GNC_CFLAG_I)) { //putCode( VM_NF, node_pos ); // invert flag if ((mCodeAreaPos) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_NF); mCodeAreaPos++; } } mCodeArea[addr1 + 1] = (short)(mCodeAreaPos - addr1); // patch if ((restype & RT_CFLAG) == 0) { // requested result type is not condition flag if ((resaddr1 == GNC_CFLAG || resaddr1 == GNC_CFLAG_I) || resaddr1 <= 0) { //putCode( inv ? VM_SETNF : VM_SETF, node_pos ); //putCode( frame.value, node_pos ); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(inv ? VM_SETNF : VM_SETF); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; resaddr1 = frame.value; frame.value++; } else { //putCode( inv ? VM_SETNF : VM_SETF, node_pos ); //putCode( resaddr1, node_pos ); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(inv ? VM_SETNF : VM_SETF); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr1); mCodeAreaPos++; } } return (restype & RT_CFLAG) != 0 ? (inv ? GNC_CFLAG_I : GNC_CFLAG) : resaddr1; } case Token.T_INSTANCEOF: { // 'instanceof' operator // instanceof operator int resaddr1; int resaddr2; resaddr1 = GenNodeCode(frame, node.GetNode(0), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); if (resaddr1 <= 0) { //putCode( VM_CP, node_pos ); //putCode( frame.value, node_pos ); //putCode( resaddr1, node_pos ); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_CP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr1); mCodeAreaPos++; resaddr1 = frame.value; frame.value++; } resaddr2 = GenNodeCode(frame, node.GetNode(1), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); //putCode( VM_CHKINS, node_pos ); //putCode( resaddr1, node_pos ); //putCode( resaddr2, node_pos ); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_CHKINS); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr1); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr2); mCodeAreaPos++; return resaddr1; } case Token.T_VERTLINE: case Token.T_CHEVRON: case Token.T_AMPERSAND: case Token.T_RARITHSHIFT: case Token.T_LARITHSHIFT: case Token.T_RBITSHIFT: case Token.T_PLUS: case Token.T_MINUS: case Token.T_PERCENT: case Token.T_SLASH: case Token.T_BACKSLASH: case Token.T_ASTERISK: { // '|' operator // '^' operator // binary '&' operator // '>>' operator // '<<' operator // '>>>' operator // binary '+' operator // '-' operator // '%' operator // '/' operator // '\' operator // binary '*' operator // general two-term operator int resaddr1; int resaddr2; if (param.mSubType != stNone) { ErrorMsg(Error.CannotModifyLHS); } resaddr1 = GenNodeCode(frame, node.GetNode(0), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); if (resaddr1 <= 0) { //putCode( VM_CP, node_pos ); //putCode( frame.value, node_pos ); //putCode( resaddr1, node_pos ); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_CP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr1); mCodeAreaPos++; resaddr1 = frame.value; frame.value++; } resaddr2 = GenNodeCode(frame, node.GetNode(1), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); int code = 0; switch (node.GetOpecode()) { case Token.T_VERTLINE: { // sucking... code = VM_BOR; break; } case Token.T_CHEVRON: { code = VM_BXOR; break; } case Token.T_AMPERSAND: { code = VM_BAND; break; } case Token.T_RARITHSHIFT: { code = VM_SAR; break; } case Token.T_LARITHSHIFT: { code = VM_SAL; break; } case Token.T_RBITSHIFT: { code = VM_SR; break; } case Token.T_PLUS: { code = VM_ADD; break; } case Token.T_MINUS: { code = VM_SUB; break; } case Token.T_PERCENT: { code = VM_MOD; break; } case Token.T_SLASH: { code = VM_DIV; break; } case Token.T_BACKSLASH: { code = VM_IDIV; break; } case Token.T_ASTERISK: { code = VM_MUL; break; } } //putCode( code, node_pos ); //putCode( resaddr1, node_pos ); //putCode( resaddr2, node_pos ); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(code); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr1); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr2); mCodeAreaPos++; return resaddr1; } case Token.T_NOTEQUAL: case Token.T_EQUALEQUAL: case Token.T_DISCNOTEQUAL: case Token.T_DISCEQUAL: case Token.T_LT: case Token.T_GT: case Token.T_LTOREQUAL: case Token.T_GTOREQUAL: { // '!=' operator // '==' operator // '!==' operator // '===' operator // '<' operator // '>' operator // '<=' operator // '>=' operator // comparison operators int resaddr1; int resaddr2; if (param.mSubType != stNone) { ErrorMsg(Error.CannotModifyLHS); } resaddr1 = GenNodeCode(frame, node.GetNode(0), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); if ((restype & RT_CFLAG) == 0) { if (resaddr1 <= 0) { //putCode( VM_CP, node_pos ); //putCode( frame.value, node_pos ); //putCode( resaddr1, node_pos ); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_CP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr1); mCodeAreaPos++; resaddr1 = frame.value; frame.value++; } } resaddr2 = GenNodeCode(frame, node.GetNode(1), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); int code1 = 0; int code2 = 0; switch (node.GetOpecode()) { case Token.T_NOTEQUAL: { code1 = VM_CEQ; code2 = VM_SETNF; break; } case Token.T_EQUALEQUAL: { code1 = VM_CEQ; code2 = VM_SETF; break; } case Token.T_DISCNOTEQUAL: { code1 = VM_CDEQ; code2 = VM_SETNF; break; } case Token.T_DISCEQUAL: { code1 = VM_CDEQ; code2 = VM_SETF; break; } case Token.T_LT: { code1 = VM_CLT; code2 = VM_SETF; break; } case Token.T_GT: { code1 = VM_CGT; code2 = VM_SETF; break; } case Token.T_LTOREQUAL: { code1 = VM_CGT; code2 = VM_SETNF; break; } case Token.T_GTOREQUAL: { code1 = VM_CLT; code2 = VM_SETNF; break; } } //putCode( code1, node_pos ); //putCode( resaddr1, node_pos ); //putCode( resaddr2, node_pos ); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(code1); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr1); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr2); mCodeAreaPos++; if ((restype & RT_CFLAG) == 0) { //putCode( code2, node_pos ); //putCode( resaddr1, node_pos ); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } mCodeArea[mCodeAreaPos] = (short)(code2); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr1); mCodeAreaPos++; } return (restype & RT_CFLAG) != 0 ? (code2 == VM_SETNF ? GNC_CFLAG_I : GNC_CFLAG) : resaddr1; } case Token.T_EXCRAMATION: { // ここから一气に // pre-positioned '!' operator // logical not if ((param.mSubType != stNone)) { ErrorMsg(Error.CannotModifyLHS); } resaddr = GenNodeCode(frame, node.GetNode(0), restype, reqresaddr, new InterCodeGenerator.SubParam ()); if ((restype & RT_CFLAG) == 0) { // value as return value required if (!(resaddr > 0)) { //putCode(VM_CP, node_pos); //putCode( frame.value, node_pos); //putCode( resaddr, node_pos); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_CP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; resaddr = frame.value; frame.value++; } //putCode(VM_LNOT, node_pos); //putCode( resaddr, node_pos); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_LNOT); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; return resaddr; } else { // condifion flag required if (!(resaddr == GNC_CFLAG || resaddr == GNC_CFLAG_I)) { //putCode(VM_TF, node_pos); //putCode( resaddr); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_TF); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; return GNC_CFLAG; } return resaddr == GNC_CFLAG_I ? GNC_CFLAG : GNC_CFLAG_I; } goto case Token.T_TILDE; } case Token.T_TILDE: case Token.T_SHARP: case Token.T_DOLLAR: case Token.T_UPLUS: case Token.T_UMINUS: case Token.T_INVALIDATE: case Token.T_ISVALID: case Token.T_EVAL: case Token.T_INT: case Token.T_REAL: case Token.T_STRING: case Token.T_OCTET: { // invert flag // '~' operator // '#' operator // '$' operator // unary '+' operator // unary '-' operator // 'invalidate' operator // 'isvalid' operator // post-positioned '!' operator // 'int' operator // 'real' operator // 'string' operator // 'octet' operator // general unary operators if ((param.mSubType != stNone)) { ErrorMsg(Error.CannotModifyLHS); } resaddr = GenNodeCode(frame, node.GetNode(0), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); if (!(resaddr > 0)) { //putCode(VM_CP, node_pos); //putCode( frame.value, node_pos); //putCode( resaddr, node_pos); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_CP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; resaddr = frame.value; frame.value++; } int code = 0; switch (node.GetOpecode()) { case Token.T_TILDE: { code = VM_BNOT; break; } case Token.T_SHARP: { code = VM_ASC; break; } case Token.T_DOLLAR: { code = VM_CHR; break; } case Token.T_UPLUS: { code = VM_NUM; break; } case Token.T_UMINUS: { code = VM_CHS; break; } case Token.T_INVALIDATE: { code = VM_INV; break; } case Token.T_ISVALID: { code = VM_CHKINV; break; } case Token.T_TYPEOF: { code = VM_TYPEOF; break; } case Token.T_EVAL: { code = (restype & RT_NEEDED) != 0 ? VM_EVAL : VM_EEXP; // warn if T_EVAL is used in non-global position if (TJS.mWarnOnNonGlobalEvalOperator && mContextType != ContextType.TOP_LEVEL) { OutputWarning(Error.WarnEvalOperator); } break; } case Token.T_INT: { code = VM_INT; break; } case Token.T_REAL: { code = VM_REAL; break; } case Token.T_STRING: { code = VM_STR; break; } case Token.T_OCTET: { code = VM_OCTET; break; } } //putCode(code, node_pos); //putCode( resaddr, node_pos); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(code); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; return resaddr; } case Token.T_TYPEOF: { // 'typeof' operator // typeof if ((param.mSubType != stNone)) { ErrorMsg(Error.CannotModifyLHS); } bool haspropnode; ExprNode cnode = node.GetNode(0); if (cnode.GetOpecode() == Token.T_DOT || cnode.GetOpecode() == Token.T_LBRACKET || cnode.GetOpecode() == Token.T_WITHDOT) { haspropnode = true; } else { haspropnode = false; } if (haspropnode) { // has property access node InterCodeGenerator.SubParam param2 = new InterCodeGenerator.SubParam(); param2.mSubType = stTypeOf; return GenNodeCode(frame, cnode, RT_NEEDED, 0, param2); } else { // normal operation resaddr = GenNodeCode(frame, cnode, RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); if (!(resaddr > 0)) { //putCode(VM_CP, node_pos); //putCode( frame.value, node_pos); //putCode( resaddr, node_pos); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_CP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; resaddr = frame.value; frame.value++; } //putCode(VM_TYPEOF, node_pos); //putCode( resaddr, node_pos); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_TYPEOF); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; return resaddr; } goto case Token.T_DELETE; } case Token.T_DELETE: case Token.T_INCREMENT: case Token.T_DECREMENT: case Token.T_POSTINCREMENT: case Token.T_POSTDECREMENT: { // 'delete' operator // pre-positioned '++' operator // pre-positioned '--' operator // post-positioned '++' operator // post-positioned '--' operator // delete, typeof, increment and decrement if ((param.mSubType != stNone)) { ErrorMsg(Error.CannotModifyLHS); } InterCodeGenerator.SubParam param2 = new InterCodeGenerator.SubParam(); switch (node.GetOpecode()) { case Token.T_TYPEOF: { param2.mSubType = stTypeOf; break; } case Token.T_DELETE: { param2.mSubType = stDelete; break; } case Token.T_INCREMENT: { param2.mSubType = stPreInc; break; } case Token.T_DECREMENT: { param2.mSubType = stPreDec; break; } case Token.T_POSTINCREMENT: { param2.mSubType = stPostInc; break; } case Token.T_POSTDECREMENT: { param2.mSubType = stPostDec; break; } } return GenNodeCode(frame, node.GetNode(0), restype, reqresaddr, param2); } case Token.T_LPARENTHESIS: case Token.T_NEW: { // '( )' operator // 'new' operator // function call or create-new object // does (*node)[0] have a node that acceesses any properties ? bool haspropnode; bool hasnonlocalsymbol; ExprNode cnode = node.GetNode(0); if (node.GetOpecode() == Token.T_LPARENTHESIS && (cnode.GetOpecode() == Token.T_DOT || cnode.GetOpecode() == Token.T_LBRACKET)) { haspropnode = true; } else { haspropnode = false; } // does (*node)[0] have a node that accesses non-local functions ? if (node.GetOpecode() == Token.T_LPARENTHESIS && cnode.GetOpecode() == Token.T_SYMBOL) { if (mAsGlobalContextMode) { hasnonlocalsymbol = true; } else { string str = cnode.GetValue().AsString(); if (mNamespace.Find(str) == -1) { hasnonlocalsymbol = true; } else { hasnonlocalsymbol = false; } } } else { hasnonlocalsymbol = false; } // flag which indicates whether to do direct or indirect call access bool do_direct_access = haspropnode || hasnonlocalsymbol; // reserve frame if (!do_direct_access && (restype & RT_NEEDED) != 0) { frame.value++; } // reserve the frame for a result value // generate function call codes StartFuncArg(); int framestart = frame.value; int res; try { // arguments is if (node.GetNode(1).GetSize() == 1 && node.GetNode(1).GetNode(0) == null) { } else { // empty // exist GenNodeCode(frame, node.GetNode(1), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); } // compilation of expression that represents the function InterCodeGenerator.SubParam param2 = new InterCodeGenerator.SubParam(); if (do_direct_access) { param2.mSubType = stFuncCall; // creates code with stFuncCall res = GenNodeCode(frame, node.GetNode(0), restype, reqresaddr, param2); } else { param2.mSubType = stNone; resaddr = GenNodeCode(frame, node.GetNode(0), RT_NEEDED, 0, param2); // code generatio of function calling if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(node.GetOpecode() == Token.T_NEW ? VM_NEW : VM_CALL ); mCodeAreaPos++; res = ((restype & RT_NEEDED) != 0 ? (framestart - 1) : 0); mCodeArea[mCodeAreaPos] = (short)(res); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; // generate argument code GenerateFuncCallArgCode(); // clears the frame ClearFrame(frame, framestart); } } finally { EndFuncArg(); } return res; } case Token.T_ARG: { // a function argument if (node.GetSize() >= 2) { if (node.GetNode(1) != null) { GenNodeCode(frame, node.GetNode(1), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); } } if (node.GetNode(0) != null) { ExprNode n = node.GetNode(0); if (n.GetOpecode() == Token.T_EXPANDARG) { // expanding argument if (n.GetNode(0) != null) { AddFuncArg(GenNodeCode(frame, n.GetNode(0), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()), fatExpand); } else { AddFuncArg(0, fatUnnamedExpand); } } else { AddFuncArg(GenNodeCode(frame, node.GetNode(0), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()), fatNormal); } } else { AddFuncArg(0, fatNormal); } return 0; } case Token.T_OMIT: { // omitting of the function arguments AddOmitArg(); return 0; } case Token.T_DOT: case Token.T_LBRACKET: { // '.' operator // '[ ]' operator // member access ( direct or indirect ) bool direct = node.GetOpecode() == Token.T_DOT; int dp; InterCodeGenerator.SubParam param2 = new InterCodeGenerator.SubParam(); param2.mSubType = stNone; resaddr = GenNodeCode(frame, node.GetNode(0), RT_NEEDED, 0, param2); if (direct) { dp = PutData(node.GetNode(1).GetValue()); } else { dp = GenNodeCode(frame, node.GetNode(1), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); } switch (param.mSubType) { case stNone: case stIgnorePropGet: { if ((mCodeAreaPos + 3) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } if (param.mSubType == stNone) { //putCode(direct ? VM_GPD : VM_GPI, node_pos); mCodeArea[mCodeAreaPos] = (short)(direct ? VM_GPD : VM_GPI); mCodeAreaPos++; } else { //putCode(direct ? VM_GPDS : VM_GPIS, node_pos); mCodeArea[mCodeAreaPos] = (short)(direct ? VM_GPDS : VM_GPIS); mCodeAreaPos++; } //putCode( frame.value, node_pos); //putCode( resaddr, node_pos); //putCode( dp, node_pos); mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(dp); mCodeAreaPos++; frame.value++; return frame.value - 1; } case stEqual: case stIgnorePropSet: { if ((mCodeAreaPos + 3) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } if (param.mSubType == stEqual) { if (node.GetNode(0).GetOpecode() == Token.T_THIS_PROXY) { //putCode(direct ? VM_SPD : VM_SPI, node_pos); mCodeArea[mCodeAreaPos] = (short)(direct ? VM_SPD : VM_SPI); mCodeAreaPos++; } else { //putCode(direct ? VM_SPDE : VM_SPIE, node_pos); mCodeArea[mCodeAreaPos] = (short)(direct ? VM_SPDE : VM_SPIE); mCodeAreaPos++; } } else { //putCode(direct ? VM_SPDS : VM_SPIS, node_pos); mCodeArea[mCodeAreaPos] = (short)(direct ? VM_SPDS : VM_SPIS); mCodeAreaPos++; } //putCode( resaddr, node_pos); //putCode( dp, node_pos); //putCode( param.mSubAddress, node_pos); mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(dp); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(param.mSubAddress); mCodeAreaPos++; return param.mSubAddress; } case stBitAND: case stBitOR: case stBitXOR: case stSub: case stAdd: case stMod: case stDiv: case stIDiv: case stMul: case stLogOR: case stLogAND: case stSAR: case stSAL: case stSR: { //putCode( param.mSubType + (direct?1:2), node_pos); // here adds 1 or 2 to the ope-code // ( see the ope-code's positioning order ) //putCode(( (restype & RT_NEEDED) != 0 ? frame.value : 0), node_pos); //putCode( resaddr, node_pos); //putCode( dp, node_pos); //putCode( param.mSubAddress, node_pos); if ((mCodeAreaPos + 4) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(param.mSubType + (direct ? 1 : 2)); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(((restype & RT_NEEDED) != 0 ? frame.value : 0)); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(dp); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(param.mSubAddress); mCodeAreaPos++; if ((restype & RT_NEEDED) != 0) { frame.value++; } return (restype & RT_NEEDED) != 0 ? frame.value - 1 : 0; } case stPreInc: case stPreDec: { //putCode((param.mSubType == stPreInc ? VM_INC : VM_DEC) + (direct? 1:2), node_pos); //putCode(((restype & RT_NEEDED) != 0 ? frame.value : 0), node_pos); //putCode( resaddr, node_pos); //putCode( dp, node_pos); if ((mCodeAreaPos + 3) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)((param.mSubType == stPreInc ? VM_INC : VM_DEC) + (direct ? 1 : 2)); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(((restype & RT_NEEDED) != 0 ? frame.value : 0)); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(dp); mCodeAreaPos++; if ((restype & RT_NEEDED) != 0) { frame.value++; } return (restype & RT_NEEDED) != 0 ? frame.value - 1 : 0; } case stPostInc: case stPostDec: { int retresaddr = 0; if ((restype & RT_NEEDED) != 0) { // need result ... //putCode(direct ? VM_GPD : VM_GPI, node_pos); //putCode( frame.value, node_pos); //putCode( resaddr, node_pos); //putCode( dp, node_pos); if ((mCodeAreaPos + 3) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(direct ? VM_GPD : VM_GPI); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(dp); mCodeAreaPos++; retresaddr = frame.value; frame.value++; } //putCode( (param.mSubType == stPostInc ? VM_INC : VM_DEC) + (direct? 1:2), node_pos); //putCode( 0, node_pos ); //putCode( resaddr, node_pos ); //putCode( dp, node_pos ); if ((mCodeAreaPos + 3) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)((param.mSubType == stPostInc ? VM_INC : VM_DEC) + (direct ? 1 : 2)); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(dp); mCodeAreaPos++; return retresaddr; } case stTypeOf: { // typeof //putCode(direct? VM_TYPEOFD:VM_TYPEOFI, node_pos); //putCode(( (restype & RT_NEEDED) != 0 ? frame.value:0), node_pos); //putCode( resaddr, node_pos); //putCode( dp, node_pos); if ((mCodeAreaPos + 3) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(direct ? VM_TYPEOFD : VM_TYPEOFI); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(((restype & RT_NEEDED) != 0 ? frame.value : 0)); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(dp); mCodeAreaPos++; if ((restype & RT_NEEDED) != 0) { frame.value++; } return (restype & RT_NEEDED) != 0 ? frame.value - 1 : 0; } case stDelete: { // deletion //putCode(direct? VM_DELD:VM_DELI, node_pos); //putCode(( (restype & RT_NEEDED) != 0 ? frame.value:0), node_pos); //putCode( resaddr, node_pos); //putCode( dp, node_pos); if ((mCodeAreaPos + 3) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(direct ? VM_DELD : VM_DELI); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(((restype & RT_NEEDED) != 0 ? frame.value : 0)); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(dp); mCodeAreaPos++; if ((restype & RT_NEEDED) != 0) { frame.value++; } return (restype & RT_NEEDED) != 0 ? frame.value - 1 : 0; } case stFuncCall: { // function call //putCode(direct ? VM_CALLD:VM_CALLI, node_pos); //putCode(( (restype & RT_NEEDED) != 0 ? frame.value:0), node_pos); // result target //putCode( resaddr, node_pos); // the object //putCode( dp, node_pos); // function name if ((mCodeAreaPos + 3) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(direct ? VM_CALLD : VM_CALLI); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(((restype & RT_NEEDED) != 0 ? frame.value : 0)); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(dp); mCodeAreaPos++; // generate argument code GenerateFuncCallArgCode(); // extend frame and return if ((restype & RT_NEEDED) != 0) { frame.value++; } return (restype & RT_NEEDED) != 0 ? frame.value - 1 : 0; } default: { ErrorMsg(Error.CannotModifyLHS); return 0; break; } } goto case Token.T_SYMBOL; } case Token.T_SYMBOL: { // symbol // accessing to a variable int n; if (mAsGlobalContextMode) { n = -1; } else { // global mode cannot access local variables string str = node.GetValue().AsString(); n = mNamespace.Find(str); } if (n != -1) { bool isstnone = !(param.mSubType != stNone); if (!isstnone) { switch (param.mSubType) { case stEqual: { // substitution, or like it //putCode(VM_CP, node_pos); //putCode((-n-mVariableReserveCount-1), node_pos); //putCode( param.mSubAddress, node_pos); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_CP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(-n - mVariableReserveCount - 1); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(param.mSubAddress); mCodeAreaPos++; break; } case stBitAND: case stBitOR: case stBitXOR: case stSub: case stAdd: case stMod: case stDiv: case stIDiv: case stMul: case stLogOR: case stLogAND: case stSAR: case stSAL: case stSR: { //putCode(param.mSubType, node_pos); //putCode((-n-mVariableReserveCount-1), node_pos); //putCode( param.mSubAddress, node_pos); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(param.mSubType); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(-n - mVariableReserveCount - 1); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(param.mSubAddress); mCodeAreaPos++; return (restype & RT_NEEDED) != 0 ? -n - mVariableReserveCount - 1 : 0; } case stPreInc: { // pre-positioning //putCode(VM_INC, node_pos); //putCode((-n-mVariableReserveCount-1), node_pos); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_INC); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(-n - mVariableReserveCount - 1); mCodeAreaPos++; return (restype & RT_NEEDED) != 0 ? -n - mVariableReserveCount - 1 : 0; } case stPreDec: { // pre- //putCode(VM_DEC, node_pos); //putCode((-n-mVariableReserveCount-1), node_pos); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_DEC); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(-n - mVariableReserveCount - 1); mCodeAreaPos++; return (restype & RT_NEEDED) != 0 ? -n - mVariableReserveCount - 1 : 0; } case stPostInc: { // post- if ((restype & RT_NEEDED) != 0) { //putCode(VM_CP, node_pos); //putCode( frame.value, node_pos); //putCode((-n-mVariableReserveCount-1), node_pos); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_CP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(-n - mVariableReserveCount - 1); mCodeAreaPos++; frame.value++; } //putCode(VM_INC, node_pos); //putCode((-n-mVariableReserveCount-1), node_pos); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_INC); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(-n - mVariableReserveCount - 1); mCodeAreaPos++; return (restype & RT_NEEDED) != 0 ? frame.value - 1 : 0; } case stPostDec: { // post- if ((restype & RT_NEEDED) != 0) { //putCode(VM_CP, node_pos); //putCode( frame.value, node_pos); //putCode((-n-mVariableReserveCount-1), node_pos); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_CP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(-n - mVariableReserveCount - 1); mCodeAreaPos++; frame.value++; } //putCode(VM_DEC, node_pos); //putCode((-n-mVariableReserveCount-1), node_pos); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_DEC); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(-n - mVariableReserveCount - 1); mCodeAreaPos++; return (restype & RT_NEEDED) != 0 ? frame.value - 1 : 0; } case stDelete: { // deletion string str = node.GetValue().AsString(); mNamespace.Remove(str); if ((restype & RT_NEEDED) != 0) { int dp = PutData(new Variant(1)); // true //putCode(VM_CONST, node_pos); //putCode( frame.value, node_pos); //putCode( dp, node_pos); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_CONST); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(dp); mCodeAreaPos++; return frame.value - 1; } return 0; } default: { ErrorMsg(Error.CannotModifyLHS); break; } } return 0; } else { // read string str = node.GetValue().AsString(); int n1 = mNamespace.Find(str); return -n1 - mVariableReserveCount - 1; } } else { // n==-1 ( indicates the variable is not found in the local ) // assume the variable is in "this". // make nodes that refer "this" and process it ExprNode nodep = new ExprNode(); nodep.SetOpecode(Token.T_DOT); nodep.SetPosition(node_pos); ExprNode node1 = new ExprNode(); mNodeToDeleteVector.AddItem(node1); nodep.Add(node1); node1.SetOpecode(mAsGlobalContextMode ? Token.T_GLOBAL : Token.T_THIS_PROXY); node1.SetPosition(node_pos); ExprNode node2 = new ExprNode(); mNodeToDeleteVector.AddItem(node2); nodep.Add(node2); node2.SetOpecode(Token.T_SYMBOL); node2.SetPosition(node_pos); node2.SetValue(node.GetValue()); return GenNodeCode(frame, nodep, restype, reqresaddr, param); } goto case Token.T_IGNOREPROP; } case Token.T_IGNOREPROP: case Token.T_PROPACCESS: { // unary '&' operator // unary '*' operator if (node.GetOpecode() == (TJS.mUnaryAsteriskIgnoresPropAccess ? Token.T_PROPACCESS : Token.T_IGNOREPROP)) { // unary '&' operator // substance accessing (ignores property operation) InterCodeGenerator.SubParam sp = new InterCodeGenerator.SubParam(param); if (sp.mSubType == stNone) { sp.mSubType = stIgnorePropGet; } else { if (sp.mSubType == stEqual) { sp.mSubType = stIgnorePropSet; } else { ErrorMsg(Error.CannotModifyLHS); } } return GenNodeCode(frame, node.GetNode(0), restype, reqresaddr, sp); } else { // unary '*' operator // force property access resaddr = GenNodeCode(frame, node.GetNode(0), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); switch (param.mSubType) { case stNone: { // read from property object //putCode(VM_GETP, node_pos); //putCode( frame.value, node_pos); //putCode( resaddr, node_pos); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_GETP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; frame.value++; return frame.value - 1; } case stEqual: { // write to property object //putCode(VM_SETP, node_pos); //putCode( resaddr, node_pos); //putCode( param.mSubAddress, node_pos); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_SETP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(param.mSubAddress); mCodeAreaPos++; return param.mSubAddress; } case stBitAND: case stBitOR: case stBitXOR: case stSub: case stAdd: case stMod: case stDiv: case stIDiv: case stMul: case stLogOR: case stLogAND: case stSAR: case stSAL: case stSR: { //putCode(param.mSubType + 3, node_pos); // +3 : property access // ( see the ope-code's positioning order ) //putCode(((restype & RT_NEEDED) != 0 ? frame.value: 0), node_pos); //putCode( resaddr, node_pos); //putCode( param.mSubAddress, node_pos); if ((mCodeAreaPos + 3) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(param.mSubType + 3); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(((restype & RT_NEEDED) != 0 ? frame.value : 0)); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(param.mSubAddress); mCodeAreaPos++; if ((restype & RT_NEEDED) != 0) { frame.value++; } return (restype & RT_NEEDED) != 0 ? frame.value - 1 : 0; } case stPreInc: case stPreDec: { //putCode((param.mSubType == stPreInc ? VM_INC : VM_DEC) + 3, node_pos); //putCode(((restype & RT_NEEDED) != 0 ? frame.value : 0), node_pos); //putCode( resaddr, node_pos); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)((param.mSubType == stPreInc ? VM_INC : VM_DEC) + 3); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(((restype & RT_NEEDED) != 0 ? frame.value : 0)); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; if ((restype & RT_NEEDED) != 0) { frame.value++; } return (restype & RT_NEEDED) != 0 ? frame.value - 1 : 0; } case stPostInc: case stPostDec: { int retresaddr = 0; if ((restype & RT_NEEDED) != 0) { // need result ... //putCode(VM_GETP, node_pos); //putCode( frame.value, node_pos); //putCode( resaddr, node_pos); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_GETP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; retresaddr = frame.value; frame.value++; } //putCode((param.mSubType == stPostInc ? VM_INC : VM_DEC) + 3, node_pos); //putCode( 0, node_pos); //putCode( resaddr, node_pos); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)((param.mSubType == stPostInc ? VM_INC : VM_DEC) + 3); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; return retresaddr; } default: { ErrorMsg(Error.CannotModifyLHS); return 0; break; } } } goto case Token.T_SUPER; } case Token.T_SUPER: { // 'super' // refer super class //int dp; ExprNode node1; if (mParent != null && mParent.mContextType == ContextType.PROPERTY) { if ((node1 = mParent.mParent.mSuperClassExpr) == null) { ErrorMsg(Error.CannotGetSuper); return 0; } } else { if (mParent == null || (node1 = mParent.mSuperClassExpr) == null) { ErrorMsg(Error.CannotGetSuper); return 0; } } mAsGlobalContextMode = true; // the code must be generated in global context try { resaddr = GenNodeCode(frame, node1, restype, reqresaddr, param); } finally { mAsGlobalContextMode = false; } return resaddr; } case Token.T_THIS: { if (param.mSubType != 0) { ErrorMsg(Error.CannotModifyLHS); } return -1; } case Token.T_THIS_PROXY: { // this-proxy is a special register that points // both "objthis" and "global" // if refering member is not in "objthis", this-proxy // refers "global". return -mVariableReserveCount; } case Token.T_WITHDOT: { // unary '.' operator // dot operator omitting object name ExprNode nodep = new ExprNode(); nodep.SetOpecode(Token.T_DOT); nodep.SetPosition(node_pos); ExprNode node1 = new ExprNode(); mNodeToDeleteVector.AddItem(node1); nodep.Add(node1); node1.SetOpecode(Token.T_WITHDOT_PROXY); node1.SetPosition(node_pos); nodep.Add(node.GetNode(0)); return GenNodeCode(frame, nodep, restype, reqresaddr, param); } case Token.T_WITHDOT_PROXY: { // virtual left side of "." operator which omits object // search in NestVector int i = mNestVector.Count - 1; for (; i >= 0; i--) { InterCodeGenerator.NestData data = mNestVector[i]; if (data.Type == ntWith) { // found return data.RefRegister; } } goto case Token.T_GLOBAL; } case Token.T_GLOBAL: { // not found in NestVector ... // NO "break" HERE!!!!!! (pass thru to global) if (param.mSubType != 0) { ErrorMsg(Error.CannotModifyLHS); } if ((restype & RT_NEEDED) == 0) { return 0; } //putCode(VM_GLOBAL, node_pos); //putCode( frame.value, node_pos); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_GLOBAL); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; frame.value++; return frame.value - 1; } case Token.T_INLINEARRAY: { // inline array int arraydp = PutData(new Variant("Array")); // global %frame0 // gpd %frame1, %frame0 . #arraydp // #arraydp = Array int frame0 = frame.value; if ((mCodeAreaPos + 12) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } //putCode(VM_GLOBAL, node_pos); //putCode((frame.value+0), node_pos); mCodeArea[mCodeAreaPos] = (short)(VM_GLOBAL); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; //putCode(VM_GPD, node_pos); //putCode((frame.value+1), node_pos); //putCode((frame.value+0), node_pos); //putCode( arraydp, node_pos); mCodeArea[mCodeAreaPos] = (short)(VM_GPD); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value + 1); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(arraydp); mCodeAreaPos++; // new %frame0, %frame1() //putCode(VM_NEW, node_pos); //putCode((frame.value+0), node_pos); //putCode((frame.value+1), node_pos); //putCode(0); // argument count for "new Array" mCodeArea[mCodeAreaPos] = (short)(VM_NEW); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value + 1); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; // const %frame1, #zerodp int zerodp = PutData(new Variant(0)); //putCode(VM_CONST, node_pos); //putCode((frame.value+1), node_pos); //putCode( zerodp, node_pos); mCodeArea[mCodeAreaPos] = (short)(VM_CONST); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value + 1); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(zerodp); mCodeAreaPos++; frame.value += 2; mArrayArgStack.Push(new InterCodeGenerator.ArrayArg()); mArrayArgStack.Peek().Object = frame0; mArrayArgStack.Peek().Counter = frame0 + 1; int nodesize = node.GetSize(); if (node.GetSize() == 1 && node.GetNode(0).GetNode(0) == null) { } else { // the element is empty for (int i = 0; i < nodesize; i++) { GenNodeCode(frame, node.GetNode(i), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); } } // elements mArrayArgStack.Pop(); return (restype & RT_NEEDED) != 0 ? (frame0) : 0; } case Token.T_ARRAYARG: { // an element of inline array int framestart = frame.value; resaddr = node.GetNode(0) != null ? GenNodeCode(frame, node.GetNode(0), RT_NEEDED , 0, new InterCodeGenerator.SubParam()) : 0; // spis %object.%count, %resaddr //putCode(VM_SPIS, node_pos); //putCode((mArrayArgStack.peek().Object)); //putCode((mArrayArgStack.peek().Counter)); //putCode( resaddr); if ((mCodeAreaPos + 5) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_SPIS); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(mArrayArgStack.Peek().Object); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(mArrayArgStack.Peek().Counter); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; // inc %count //putCode(VM_INC); //putCode((mArrayArgStack.peek().Counter)); mCodeArea[mCodeAreaPos] = (short)(VM_INC); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(mArrayArgStack.Peek().Counter); mCodeAreaPos++; ClearFrame(frame, framestart); return 0; } case Token.T_INLINEDIC: { // inline dictionary int dicdp = PutData(new Variant("Dictionary")); // global %frame0 // gpd %frame1, %frame0 . #dicdp // #dicdp = Dictionary int frame0 = frame.value; if ((mCodeAreaPos + 9) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } //putCode(VM_GLOBAL, node_pos); //putCode((frame.value+0), node_pos); mCodeArea[mCodeAreaPos] = (short)(VM_GLOBAL); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; //putCode(VM_GPD, node_pos); //putCode((frame.value+1), node_pos); //putCode((frame.value+0), node_pos); //putCode( dicdp, node_pos); mCodeArea[mCodeAreaPos] = (short)(VM_GPD); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value + 1); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(dicdp); mCodeAreaPos++; // new %frame0, %frame1() //putCode(VM_NEW, node_pos); //putCode((frame.value+0), node_pos); //putCode((frame.value+1), node_pos); //putCode(0); // argument count for "Dictionary" class mCodeArea[mCodeAreaPos] = (short)(VM_NEW); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value + 1); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; frame.value += 2; ClearFrame(frame, frame0 + 1); // clear register at frame+1 mArrayArgStack.Push(new InterCodeGenerator.ArrayArg()); mArrayArgStack.Peek().Object = frame0; int nodesize = node.GetSize(); for (int i = 0; i < nodesize; i++) { GenNodeCode(frame, node.GetNode(i), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); } // element mArrayArgStack.Pop(); return (restype & RT_NEEDED) != 0 ? (frame0) : 0; } case Token.T_DICELM: { // an element of inline dictionary int framestart = frame.value; int name; int value; name = GenNodeCode(frame, node.GetNode(0), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); value = GenNodeCode(frame, node.GetNode(1), RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); // spis %object.%name, %value //putCode(VM_SPIS, node_pos); //putCode((mArrayArgStack.peek().Object)); //putCode( name); //putCode( value); if ((mCodeAreaPos + 3) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } mCodeArea[mCodeAreaPos] = (short)(VM_SPIS); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(mArrayArgStack.Peek().Object); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(name); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(value); mCodeAreaPos++; ClearFrame(frame, framestart); return 0; } case Token.T_REGEXP: { // constant regular expression if ((restype & RT_NEEDED) == 0) { return 0; } int regexpdp = PutData(new Variant("RegExp")); int patdp = PutData(node.GetValue()); int compiledp = PutData(new Variant("_compile")); // global %frame0 // gpd %frame1, %frame0 . #regexpdp // #regexpdp = RegExp int frame0 = frame.value; if ((mCodeAreaPos + 18) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(node_pos); } //putCode(VM_GLOBAL, node_pos); //putCode( frame.value); mCodeArea[mCodeAreaPos] = (short)(VM_GLOBAL); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; //putCode(VM_GPD); //putCode((frame.value + 1)); //putCode( frame.value); //putCode( regexpdp); mCodeArea[mCodeAreaPos] = (short)(VM_GPD); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value + 1); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(regexpdp); mCodeAreaPos++; // const frame2, patdp; //putCode(VM_CONST); //putCode((frame.value + 2)); //putCode( patdp); mCodeArea[mCodeAreaPos] = (short)(VM_CONST); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value + 2); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(patdp); mCodeAreaPos++; // new frame0 , frame1(); //putCode(VM_NEW); //putCode( frame.value); //putCode((frame.value+1)); //putCode(0); mCodeArea[mCodeAreaPos] = (short)(VM_NEW); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value + 1); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; // calld 0, frame0 . #compiledp(frame2) //putCode(VM_CALLD); //putCode( 0); //putCode( frame0); //putCode( compiledp); //putCode(1); //putCode((frame.value+2)); mCodeArea[mCodeAreaPos] = (short)(VM_CALLD); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame0); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(compiledp); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(1); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(frame.value + 2); mCodeAreaPos++; frame.value += 3; ClearFrame(frame, frame0 + 1); return frame0; } case Token.T_VOID: { if (param.mSubType != 0) { ErrorMsg(Error.CannotModifyLHS); } if ((restype & RT_NEEDED) == 0) { return 0; } return 0; } } // 0 is always void return 0; }
/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> public virtual ExprNode MakeNP1(int opecode, ExprNode node1) { // 定数の最适化 if (node1 != null && node1.GetOpecode() == Token.T_CONSTVAL) { ExprNode ret = null; switch (opecode) { case Token.T_EXCRAMATION: { ret = MakeConstValNode(node1.GetValue().GetNotValue()); break; } case Token.T_TILDE: { ret = MakeConstValNode(node1.GetValue().GetBitNotValue()); break; } case Token.T_SHARP: { Variant val = new Variant(node1.GetValue()); CharacterCodeOf(val); ret = MakeConstValNode(val); break; } case Token.T_DOLLAR: { Variant val = new Variant(node1.GetValue()); CharacterCodeFrom(val); ret = MakeConstValNode(val); break; } case Token.T_UPLUS: { Variant val = new Variant(node1.GetValue()); val.ToNumber(); ret = MakeConstValNode(val); break; } case Token.T_UMINUS: { Variant val = new Variant(node1.GetValue()); val.ChangeSign(); ret = MakeConstValNode(val); break; } case Token.T_INT: { Variant val = new Variant(node1.GetValue()); val.ToInteger(); ret = MakeConstValNode(val); break; } case Token.T_REAL: { Variant val = new Variant(node1.GetValue()); val.ToReal(); ret = MakeConstValNode(val); break; } case Token.T_STRING: { Variant val = new Variant(node1.GetValue()); val.ToString(); ret = MakeConstValNode(val); break; } case Token.T_OCTET: { Variant val = new Variant(node1.GetValue()); val.ToOctet(); ret = MakeConstValNode(val); break; } } // swtich if (ret != null) { node1.Clear(); return ret; } } ExprNode node = new ExprNode(); mNodeToDeleteVector.AddItem(node); node.SetOpecode(opecode); node.SetPosition(GetLexPos()); node.Add(node1); return node; }