// has expanding node //void addJumpList() { mJumpList.add( mCodeAreaPos ); } /// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.TJSException"></exception> public virtual void Commit() { // some context-related processing at final, and commits it if (mContextType == ContextType.CLASS) { // clean up super class proxy if (mSuperClassGetter != null) { mSuperClassGetter.Commit(); } } if (mContextType != ContextType.PROPERTY && mContextType != ContextType.SUPER_CLASS_GETTER) { int lexpos = GetLexPos(); //putCode( VM_SRV, lexpos ); //putCode( 0 ); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(lexpos); } mCodeArea[mCodeAreaPos] = (short)(VM_SRV); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; //putCode( VM_RET, -1 ); mCodeArea[mCodeAreaPos] = (short)(VM_RET); mCodeAreaPos++; } RegisterFunction(); if (mContextType != ContextType.PROPERTY && mContextType != ContextType.SUPER_CLASS_GETTER) { FixCode(); } mDataArray = new Variant[mDataArea.Count]; mDataArray = Sharpen.Collections.ToArray(mDataArea, mDataArray); mDataArea.Clear(); mDataArea = null; if (mContextType == ContextType.SUPER_CLASS_GETTER) { mMaxVariableCount = 2; } else { // always 2 mMaxVariableCount = mNamespace.GetMaxCount(); } mSuperClassExpr = null; ClearNodesToDelete(); mCode = new short[mCodeAreaPos]; System.Array.Copy(mCodeArea, 0, mCode, 0, mCodeAreaPos); // set object type info for debugging // we do thus nasty thing because the std::vector does not free its storage // even we call 'clear' method... //mNodeToDeleteVector = null; mNodeToDeleteVector = new VectorWrap<ExprNode>(); 直前でクリアされているはず mCurrentNodeVector.Clear(); // mCurrentNodeVector = null; mCurrentNodeVector = new VectorWrap<ExprNode>(); mFuncArgStack = null; mFuncArgStack = new Stack<InterCodeGenerator.FuncArg>(); mArrayArgStack = null; mArrayArgStack = new Stack<InterCodeGenerator.ArrayArg>(); mNestVector = null; mNestVector = new VectorWrap<InterCodeGenerator.NestData>(); mJumpList = null; mJumpList = new IntVector(); mFixList = null; mFixList = new AList<InterCodeGenerator.FixData>(); mNonLocalFunctionDeclVector = null; mNonLocalFunctionDeclVector = new VectorWrap<InterCodeGenerator.NonLocalFunctionDecl >(); }
/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> public virtual void EnterWithCode(ExprNode node) { // enter to "with" // "node" indicates a reference expression // this method and ExitWithCode are very similar to switch's code. // (those are more simple than that...) IntWrapper fr = new IntWrapper(mFrameBase); int resaddr = GenNodeCode(fr, node, RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); int nodepos = (node != null ? node.GetPosition() : -1); if (mFrameBase != resaddr) { // bring the reference variable to frame base top //putCode(VM_CP, nodepos); //putCode( mFrameBase, nodepos); // FrameBase points the reference value //putCode( resaddr, nodepos); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } mCodeArea[mCodeAreaPos] = (short)(VM_CP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(mFrameBase); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; } mNestVector.AddItem(new InterCodeGenerator.NestData()); mNestVector.LastElement().Type = ntWith; mNestVector.LastElement().RefRegister = mFrameBase; if (fr.value - 1 > mMaxFrameCount) { mMaxFrameCount = fr.value - 1; } mFrameBase++; // increment FrameBase if (mFrameBase - 1 > mMaxFrameCount) { mMaxFrameCount = mFrameBase - 1; } ClearFrame(fr); EnterBlock(); }
/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> public virtual void AddFunctionDeclArg(string varname, ExprNode node) { // process the function argument of declaration // varname = argument name // init = initial expression mNamespace.Add(varname); if (node != null) { int nodepos = (node != null ? node.GetPosition() : -1); //putCode(VM_CDEQ, nodepos); //putCode(-3 - mFuncDeclArgCount, nodepos); //putCode(0, nodepos); if ((mCodeAreaPos + 4) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } mCodeArea[mCodeAreaPos] = (short)(VM_CDEQ); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(-3 - mFuncDeclArgCount); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; int jmp_ip = mCodeAreaPos; //addJumpList(); mJumpList.Add(mCodeAreaPos); //putCode(VM_JNF, nodepos); //putCode(0, nodepos); mCodeArea[mCodeAreaPos] = (short)(VM_JNF); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; IntWrapper fr = new IntWrapper(mFrameBase); int resaddr = GenNodeCode(fr, node, RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); //putCode(VM_CP, nodepos); //putCode(-3 - mFuncDeclArgCount, nodepos); //putCode(resaddr, nodepos); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } mCodeArea[mCodeAreaPos] = (short)(VM_CP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(-3 - mFuncDeclArgCount); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; ClearFrame(fr); mCodeArea[jmp_ip + 1] = (short)(mCodeAreaPos - jmp_ip); } mFuncDeclArgCount++; }
// func_call_expr /// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> /// <exception cref="Kirikiri.Tjs2.TJSException"></exception> private ExprNode ExprFuncCallExpr(ExprNode node) { bool newExpression = false; if (node == null) { node = ExprPriorityExpr(); newExpression = true; } if (node != null && newExpression == false) { int token = Lex(); if (token != Token.T_LPARENTHESIS) { Error(Kirikiri.Tjs2.Error.NotFoundFuncCallLPARENTHESISError); Unlex(); } ExprNode n2 = ExprCallArgList(); token = Lex(); if (token != Token.T_RPARENTHESIS) { Error(Kirikiri.Tjs2.Error.NotFoundFuncCallRPARENTHESISError); Unlex(); } node = mInterCodeGenerator.MakeNP2(Token.T_LPARENTHESIS, node, n2); } return node; }
// unary_expr /// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> /// <exception cref="Kirikiri.Tjs2.TJSException"></exception> private ExprNode ExprUnaryExpr() { int token = Lex(); if (token == Token.T_LPARENTHESIS) { // ( の时、先读みしてトークンを切り替える token = Lex(); switch (token) { case Token.T_INT: { token = Lex(); if (token != Token.T_RPARENTHESIS) { Unlex(); ExprNode n1 = ExprUnaryExpr(); ExprNode retnode = mInterCodeGenerator.MakeNP1(Token.T_INT, n1); token = Lex(); if (token != Token.T_RPARENTHESIS) { Error(Kirikiri.Tjs2.Error.NotFoundRPARENTHESISError); Unlex(); } // syntax error return retnode; } else { Unlex(Token.T_CAST_INT, 0); } break; } case Token.T_REAL: { token = Lex(); if (token != Token.T_RPARENTHESIS) { Unlex(); ExprNode n1 = ExprUnaryExpr(); ExprNode retnode = mInterCodeGenerator.MakeNP1(Token.T_REAL, n1); token = Lex(); if (token != Token.T_RPARENTHESIS) { Error(Kirikiri.Tjs2.Error.NotFoundRPARENTHESISError); Unlex(); } // syntax error return retnode; } else { Unlex(Token.T_CAST_REAL, 0); } break; } case Token.T_STRING: { token = Lex(); if (token != Token.T_RPARENTHESIS) { Unlex(); ExprNode n1 = ExprUnaryExpr(); ExprNode retnode = mInterCodeGenerator.MakeNP1(Token.T_STRING, n1); token = Lex(); if (token != Token.T_RPARENTHESIS) { Error(Kirikiri.Tjs2.Error.NotFoundRPARENTHESISError); Unlex(); } // syntax error return retnode; } else { Unlex(Token.T_CAST_STRING, 0); } break; } case Token.T_CONST: { token = Lex(); if (token != Token.T_RPARENTHESIS) { Error(Kirikiri.Tjs2.Error.NotFoundRPARENTHESISError); Unlex(); } // syntax error Unlex(Token.T_CAST_CONST, 0); break; } default: { Unlex(); mNode = Expr(); token = Lex(); if (token != Token.T_RPARENTHESIS) { Error(Kirikiri.Tjs2.Error.NotFoundRPARENTHESISError); Unlex(); } // syntax error Unlex(Token.T_CAST_EXPR, 0); break; break; } } } else { Unlex(); } ExprNode node = ExprIncontextOfExpr(); if (node == null) { token = Lex(); switch (token) { case Token.T_EXCRAMATION: { // ! node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_EXCRAMATION, node); } case Token.T_TILDE: { // ~ node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_TILDE, node); } case Token.T_DECREMENT: { // -- node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_DECREMENT, node); } case Token.T_INCREMENT: { // ++ node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_INCREMENT, node); } case Token.T_NEW: { node = ExprFuncCallExpr(null); if (node != null) { node.SetOpecode(Token.T_NEW); } return node; } case Token.T_INVALIDATE: { node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_INVALIDATE, node); } case Token.T_ISVALID: { node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_ISVALID, node); } case Token.T_DELETE: { node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_DELETE, node); } case Token.T_TYPEOF: { node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_TYPEOF, node); } case Token.T_SHARP: { // # node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_SHARP, node); } case Token.T_DOLLAR: { // $ node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_DOLLAR, node); } case Token.T_PLUS: { // + node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_UPLUS, node); } case Token.T_MINUS: { // - node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_UMINUS, node); } case Token.T_AMPERSAND: { // & node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_IGNOREPROP, node); } case Token.T_ASTERISK: { // * node = ExprUnaryExpr(); if (node == null) { Unlex(Token.T_ASTERISK_RPARENTHESIS, 0); return null; } else { return mInterCodeGenerator.MakeNP1(Token.T_PROPACCESS, node); } goto case Token.T_CAST_INT; } case Token.T_CAST_INT: { // (int) node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_INT, node); } case Token.T_CAST_REAL: { // (real) node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_REAL, node); } case Token.T_CAST_STRING: { // (string) node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_STRING, node); } case Token.T_INT: { node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_INT, node); } case Token.T_REAL: { node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_REAL, node); } case Token.T_STRING: { node = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP1(Token.T_STRING, node); } default: { Unlex(); break; break; } } } else { token = Lex(); switch (token) { case Token.T_ISVALID: { return mInterCodeGenerator.MakeNP1(Token.T_ISVALID, node); } case Token.T_INSTANCEOF: { ExprNode n2 = ExprUnaryExpr(); return mInterCodeGenerator.MakeNP2(Token.T_INSTANCEOF, node, n2); } default: { Unlex(); break; break; } } } return node; }
/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> public virtual void CreateExtendsExprProxyCode(ExprNode node) { // create super class proxy to retrieve super class mSuperClassGetterPointer.Add(mCodeAreaPos); IntWrapper fr = new IntWrapper(mFrameBase); int resaddr = GenNodeCode(fr, node, RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); //putCode(VM_SRV); //putCode(resaddr); if ((mCodeAreaPos + 3) >= mCodeArea.Length) { ExpandCodeArea(); } mCodeArea[mCodeAreaPos] = (short)(VM_SRV); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; //put1OperandCode( VM_SRV, resaddr, -1 ); ClearFrame(fr); //putCode(VM_RET, -1 ); mCodeArea[mCodeAreaPos] = (short)(VM_RET); mCodeAreaPos++; int nodepos = (node != null ? node.GetPosition() : -1); //putCode(VM_NOP, nodepos); if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } mCodeArea[mCodeAreaPos] = (short)(VM_NOP); mCodeAreaPos++; }
/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> public virtual void CreateWhileExprCode(ExprNode node, bool doWhile) { // process the condition expression "node" if (doWhile) { DoContinuePatch(mNestVector.LastElement()); } IntWrapper fr = new IntWrapper(mFrameBase); int resaddr = GenNodeCode(fr, node, RT_NEEDED | RT_CFLAG, 0, new InterCodeGenerator.SubParam ()); int nodepos = (node != null ? node.GetPosition() : -1); bool inv = false; if (!(resaddr == GNC_CFLAG || resaddr == GNC_CFLAG_I)) { //putCode( VM_TT, nodepos ); //putCode( resaddr, nodepos ); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } mCodeArea[mCodeAreaPos] = (short)VM_TT; mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)resaddr; mCodeAreaPos++; } else { if (resaddr == GNC_CFLAG_I) { inv = true; } } ClearFrame(fr); if (!doWhile) { mNestVector.LastElement().ExitPatchVector.Add(mCodeAreaPos); //addJumpList(); mJumpList.Add(mCodeAreaPos); //putCode(inv?VM_JF:VM_JNF, nodepos); //putCode(0, nodepos); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } mCodeArea[mCodeAreaPos] = (short)(inv ? VM_JF : VM_JNF); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)0; mCodeAreaPos++; } else { int jmp_ip = mCodeAreaPos; //addJumpList(); mJumpList.Add(mCodeAreaPos); //putCode(inv?VM_JNF:VM_JF, nodepos); //putCode(mNestVector.lastElement().LoopStartIP - jmp_ip, nodepos); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } mCodeArea[mCodeAreaPos] = (short)(inv ? VM_JNF : VM_JF); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(mNestVector.LastElement().LoopStartIP - jmp_ip); mCodeAreaPos++; } }
public virtual ExprNode MakeNP3(int opecode, ExprNode node1, ExprNode node2, ExprNode node3) { // 三项演算子の最适化とかはしていない? ExprNode node = new ExprNode(); mNodeToDeleteVector.AddItem(node); node.SetOpecode(opecode); node.SetPosition(GetLexPos()); node.Add(node1); node.Add(node2); node.Add(node3); return node; }
/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> public virtual void ProcessCaseCode(ExprNode node) { // process "case expression :". // process "default :" if node == NULL. int nestsize = mNestVector.Count; if (nestsize < 3) { ErrorMsg(Error.MisplacedCase); return; } if (mNestVector[nestsize - 1].Type != ntBlock || mNestVector[nestsize - 2].Type != ntBlock || mNestVector[nestsize - 3].Type != ntSwitch) { // the stack layout must be ( from top ) // ntBlock, ntBlock, ntSwitch ErrorMsg(Error.MisplacedCase); return; } InterCodeGenerator.NestData data = mNestVector[mNestVector.Count - 3]; int patch3 = 0; //if( !data.IsFirstCase ) { // IsFirstCase と VariableCreated は同一に扱う if (!data.VariableCreated) { patch3 = mCodeAreaPos; //addJumpList(); mJumpList.Add(mCodeAreaPos); int nodepos = (node != null ? node.GetPosition() : -1); //putCode(VM_JMP, nodepos); //putCode(0, nodepos); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } mCodeArea[mCodeAreaPos] = (short)(VM_JMP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; } ExitBlock(); if (data.Patch1 != -1) { mCodeArea[data.Patch1 + 1] = (short)(mCodeAreaPos - data.Patch1); } if (node != null) { IntWrapper fr = new IntWrapper(mFrameBase); int resaddr = GenNodeCode(fr, node, RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); int nodepos = (node != null ? node.GetPosition() : -1); //putCode( VM_CEQ, nodepos); //putCode( data.RefRegister, nodepos); // compare to reference value with normal comparison //putCode( resaddr, nodepos); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } mCodeArea[mCodeAreaPos] = (short)(VM_CEQ); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(data.RefRegister); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; ClearFrame(fr); data.Patch1 = mCodeAreaPos; //addJumpList(); mJumpList.Add(mCodeAreaPos); //putCode(VM_JNF, nodepos); //putCode(0, nodepos); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } mCodeArea[mCodeAreaPos] = (short)(VM_JNF); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; } else { data.Patch1 = mCodeAreaPos; //addJumpList(); mJumpList.Add(mCodeAreaPos); int nodepos = (node != null ? node.GetPosition() : -1); //putCode(VM_JMP, nodepos); //putCode(0, nodepos); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } mCodeArea[mCodeAreaPos] = (short)(VM_JMP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; data.Patch2 = mCodeAreaPos; } // Patch2 = "default:"'s position //if( !data.IsFirstCase ) { if (!data.VariableCreated) { mCodeArea[patch3 + 1] = (short)(mCodeAreaPos - patch3); } //data.IsFirstCase = false; data.VariableCreated = false; EnterBlock(); }
/// <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; }
/// <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; }
public virtual ExprNode MakeNP0(int opecode) { ExprNode node = new ExprNode(); mNodeToDeleteVector.AddItem(node); node.SetOpecode(opecode); node.SetPosition(GetLexPos()); return node; }
public virtual ExprNode MakeConstValNode(Variant val) { ExprNode node = new ExprNode(); mNodeToDeleteVector.AddItem(node); node.SetOpecode(Token.T_CONSTVAL); node.SetValue(val); node.SetPosition(GetLexPos()); return node; }
/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> public virtual void InitLocalVariable(string name, ExprNode node) { IntWrapper fr = new IntWrapper(mFrameBase); int resaddr = GenNodeCode(fr, node, RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); AddLocalVariable(name, resaddr); ClearFrame(fr); }
/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> public virtual void CreateExprCode(ExprNode node) { // create code of node IntWrapper fr = new IntWrapper(mFrameBase); GenNodeCode(fr, node, 0, 0, new InterCodeGenerator.SubParam()); ClearFrame(fr); }
/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> public virtual void ProcessThrowCode(ExprNode node) { // process "throw". // node = expressoin to throw IntWrapper fr = new IntWrapper(mFrameBase); int resaddr = GenNodeCode(fr, node, RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); int nodepos = (node != null ? node.GetPosition() : -1); //putCode(VM_THROW, nodepos); //putCode(resaddr, nodepos); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } mCodeArea[mCodeAreaPos] = (short)(VM_THROW); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; if (fr.value - 1 > mMaxFrameCount) { mMaxFrameCount = fr.value - 1; } }
/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> public virtual void CreateExtendsExprCode(ExprNode node, bool hold) { // process class extender IntWrapper fr = new IntWrapper(mFrameBase); int resaddr = GenNodeCode(fr, node, RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); int nodepos = (node != null ? node.GetPosition() : -1); if ((mCodeAreaPos + 6) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } //putCode(VM_CHGTHIS, nodepos); //putCode(resaddr, nodepos); //putCode(-1, nodepos); mCodeArea[mCodeAreaPos] = (short)(VM_CHGTHIS); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(-1); mCodeAreaPos++; //putCode(VM_CALL, nodepos); //putCode(0, nodepos); //putCode(resaddr, nodepos); //putCode(0, nodepos); mCodeArea[mCodeAreaPos] = (short)(VM_CALL); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; if (hold) { mSuperClassExpr = node; } mFunctionRegisterCodePoint = mCodeAreaPos; // update FunctionRegisterCodePoint // create a Super Class Proxy context if (mSuperClassGetter == null) { mSuperClassGetter = new InterCodeGenerator(this, mName, mBlock, ContextType.SUPER_CLASS_GETTER ); } mSuperClassGetter.CreateExtendsExprProxyCode(node); }
public virtual void PushCurrentNode(ExprNode node) { mCurrentNodeVector.AddItem(node); }
/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> public virtual void CreateForExprCode(ExprNode node) { // process the "for"'s second clause; a condition expression mNestVector.LastElement().LoopStartIP = mCodeAreaPos; if (node != null) { int nodepos = node.GetPosition(); IntWrapper fr = new IntWrapper(mFrameBase); int resaddr = GenNodeCode(fr, node, RT_NEEDED | RT_CFLAG, 0, new InterCodeGenerator.SubParam ()); bool inv = false; if (!(resaddr == GNC_CFLAG || resaddr == GNC_CFLAG_I)) { //putCode(VM_TT, nodepos ); //putCode(resaddr, nodepos ); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } mCodeArea[mCodeAreaPos] = (short)(VM_TT); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; } else { if (resaddr == GNC_CFLAG_I) { inv = true; } } ClearFrame(fr); mNestVector.LastElement().ExitPatchVector.Add(mCodeAreaPos); //addJumpList(); mJumpList.Add(mCodeAreaPos); //putCode(inv?VM_JF:VM_JNF, nodepos); //putCode( 0, nodepos ); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } mCodeArea[mCodeAreaPos] = (short)(inv ? VM_JF : VM_JNF); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; } }
/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> public virtual void ReturnFromFunc(ExprNode node) { // precess "return" // note: the "return" positioned in global immediately returns without // execution of the remainder code. int nodepos = (node != null ? node.GetPosition() : -1); if (node == null) { // no return value //putCode( VM_SRV, nodepos ); //putCode( 0, nodepos ); // returns register #0 = void if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } mCodeArea[mCodeAreaPos] = (short)(VM_SRV); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(0); mCodeAreaPos++; } else { // generates return expression IntWrapper fr = new IntWrapper(mFrameBase); int resaddr = GenNodeCode(fr, node, RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); //putCode(VM_SRV, nodepos); //putCode( resaddr, nodepos); if ((mCodeAreaPos + 1) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } mCodeArea[mCodeAreaPos] = (short)(VM_SRV); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; ClearFrame(fr); } // clear the frame int org_framebase = mFrameBase; ClearFrame(mFrameBase, 1); mFrameBase = org_framebase; int lexpos = GetLexPos(); // check try block int i = mNestVector.Count - 1; for (; i >= 0; i--) { InterCodeGenerator.NestData data = mNestVector[i]; if (data.Type == ntTry) { //putCode(VM_EXTRY, lexpos); // exit from try-protected block if ((mCodeAreaPos) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(lexpos); } mCodeArea[mCodeAreaPos] = (short)(VM_EXTRY); mCodeAreaPos++; } } //putCode(VM_RET, lexpos); if ((mCodeAreaPos) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(lexpos); } mCodeArea[mCodeAreaPos] = (short)(VM_RET); mCodeAreaPos++; }
// factor_expr /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> /// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.TJSException"></exception> private ExprNode ExprFactorExpr() { int token = Lex(); ExprNode node = null; switch (token) { case Token.T_CONSTVAL: { node = mInterCodeGenerator.MakeNP0(Token.T_CONSTVAL); node.SetValue(mLexicalAnalyzer.GetValue(mValue)); return node; } case Token.T_SYMBOL: { node = mInterCodeGenerator.MakeNP0(Token.T_SYMBOL); node.SetValue(new Variant(mLexicalAnalyzer.GetString(mValue))); return node; } case Token.T_THIS: { return mInterCodeGenerator.MakeNP0(Token.T_THIS); } case Token.T_SUPER: { return mInterCodeGenerator.MakeNP0(Token.T_SUPER); } case Token.T_FUNCTION: { Unlex(); return ExprFuncExprDef(); } case Token.T_GLOBAL: { return mInterCodeGenerator.MakeNP0(Token.T_GLOBAL); } case Token.T_VOID: { return mInterCodeGenerator.MakeNP0(Token.T_VOID); } case Token.T_LBRACKET: { // [ Unlex(); return ExprInlineArray(); } case Token.T_PERCENT: { // % Unlex(); return ExprInlineDic(); } case Token.T_CAST_CONST: { // (const) Unlex(); return ExprConstInlineArrayOrDic(); } case Token.T_LPARENTHESIS: { // ( token = Lex(); if (token == Token.T_CONST) { token = Lex(); if (token != Token.T_RPARENTHESIS) { Error(Kirikiri.Tjs2.Error.NotFoundRPARENTHESISError); Unlex(); } // syntax error Unlex(Token.T_CAST_CONST, 0); return ExprConstInlineArrayOrDic(); } else { Unlex(); mNode = Expr(); token = Lex(); if (token != Token.T_RPARENTHESIS) { Error(Kirikiri.Tjs2.Error.NotFoundRPARENTHESISError); Unlex(); } // syntax error Unlex(Token.T_CAST_EXPR, 0); return null; } goto case Token.T_SLASHEQUAL; } case Token.T_SLASHEQUAL: { // /= mLexicalAnalyzer.SetStartOfRegExp(); token = Lex(); if (token == Token.T_REGEXP) { node = mInterCodeGenerator.MakeNP0(Token.T_REGEXP); node.SetValue(mLexicalAnalyzer.GetValue(mValue)); return node; } else { // 正规表现がない Error(Kirikiri.Tjs2.Error.NotFoundRegexError); Unlex(); } break; } case Token.T_SLASH: { // / mLexicalAnalyzer.SetStartOfRegExp(); token = Lex(); if (token == Token.T_REGEXP) { node = mInterCodeGenerator.MakeNP0(Token.T_REGEXP); node.SetValue(mLexicalAnalyzer.GetValue(mValue)); return node; } else { // 正规表现がない Error(Kirikiri.Tjs2.Error.NotFoundRegexError); Unlex(); } break; } } Unlex(); return null; }
public virtual void SetForThirdExprCode(ExprNode node) { // process the "for"'s third clause; a post-loop expression mNestVector.LastElement().PostLoopExpr = node; }
// priority_expr' /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> /// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.TJSException"></exception> private ExprNode ExprPriorityExpr1() { ExprNode node = ExprFactorExpr(); if (node == null) { int token = Lex(); if (token == Token.T_CAST_EXPR) { // (expr) node = mNode; mNode = null; return node; } else { if (token == Token.T_DOT) { mLexicalAnalyzer.SetNextIsBareWord(); token = Lex(); if (token == Token.T_SYMBOL) { ExprNode n2 = mInterCodeGenerator.MakeNP0(Token.T_CONSTVAL); n2.SetValue(mLexicalAnalyzer.GetValue(mValue)); return mInterCodeGenerator.MakeNP1(Token.T_WITHDOT, n2); } else { Error(Kirikiri.Tjs2.Error.NotFoundSymbolAfterDotError); Unlex(); } } else { Unlex(); } } } 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> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> /// <exception cref="Kirikiri.Tjs2.TJSException"></exception> private ExprNode ExprCallArgList2(ExprNode node) { int token; node = mInterCodeGenerator.MakeNP1(Token.T_ARG, node); do { ExprNode n2 = ExprCallArg(); node = mInterCodeGenerator.MakeNP2(Token.T_ARG, n2, node); token = Lex(); } while (token == Token.T_COMMA); Unlex(); return node; }
/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> public virtual void EnterSwitchCode(ExprNode node) { // enter to "switch" // "node" indicates a reference expression mNestVector.AddItem(new InterCodeGenerator.NestData()); mNestVector.LastElement().Type = ntSwitch; mNestVector.LastElement().Patch1 = -1; mNestVector.LastElement().Patch2 = -1; //mNestVector.lastElement().IsFirstCase = true; // IsFirstCase と VariableCreated は同一に扱う mNestVector.LastElement().VariableCreated = true; IntWrapper fr = new IntWrapper(mFrameBase); int resaddr = GenNodeCode(fr, node, RT_NEEDED, 0, new InterCodeGenerator.SubParam ()); if (mFrameBase != resaddr) { int nodepos = (node != null ? node.GetPosition() : -1); //putCode(VM_CP, nodepos); //putCode(mFrameBase, nodepos ); // FrameBase points the reference value //putCode(resaddr, nodepos ); if ((mCodeAreaPos + 2) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(nodepos); } mCodeArea[mCodeAreaPos] = (short)(VM_CP); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(mFrameBase); mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)(resaddr); mCodeAreaPos++; } mNestVector.LastElement().RefRegister = mFrameBase; if (fr.value - 1 > mMaxFrameCount) { mMaxFrameCount = fr.value - 1; } mFrameBase++; // increment FrameBase if (mFrameBase - 1 > mMaxFrameCount) { mMaxFrameCount = mFrameBase - 1; } ClearFrame(fr); EnterBlock(); }