public LexicalAnalyzer(Compiler block, string script, bool isexpr, bool resultneeded ) { mRetValDeque = new LongQue(); mEmbeddableExpressionDataStack = new AList<EmbeddableExpressionData>(); mValues = new AList<object>(); mBlock = block; mIsExprMode = isexpr; mResultNeeded = resultneeded; mPrevToken = -1; int scriptLen = script.Length; if (mIsExprMode) { mText = new char[scriptLen + 2]; Sharpen.Runtime.GetCharsForString(script, 0, scriptLen, mText, 0); mText[scriptLen] = ';'; mText[scriptLen + 1] = (char)0; } else { //mStream = new StringStream(script+";"); if (script.StartsWith("#!") == true) { // #! を // に置换 mText = new char[scriptLen + 1]; Sharpen.Runtime.GetCharsForString(script, 2, scriptLen, mText, 2); mText[0] = mText[1] = '/'; mText[scriptLen] = (char)0; } else { //mStream = new StringStream( "//" + script.substring(2)); mText = new char[scriptLen + 1]; Sharpen.Runtime.GetCharsForString(script, 0, scriptLen, mText, 0); mText[scriptLen] = (char)0; } } //mStream = new StringStream(script); if (CompileState.mEnableDicFuncQuickHack) { //----- dicfunc quick-hack //mDicFunc = false; // デフォルト值なので入れる必要なし //if( mIsExprMode && (script.startsWith("[") == true || script.startsWith("%[") == true) ) { char c = script[0]; if (mIsExprMode && (c == '[' || (c == '%' && script[1] == '['))) { mDicFunc = true; } } //mIfLevel = 0; //mPrevPos = 0; //mNestLevel = 0; mIsFirst = true; //mRegularExpression = false; //mBareWord = false; PutValue(null); }
public Lexer(Compiler block, string script, bool isexpr, bool resultneeded) : base() { InitReservedWordsHashTable(); mRetValDeque = new Queue<TokenPair>(); mEmbeddableExpressionDataStack = new AList<EmbeddableExpressionData>(); mValues = new AList<object>(); mBlock = block; mIsExprMode = isexpr; mResultNeeded = resultneeded; mPrevToken = -1; if (mIsExprMode) { mStream = new StringStream(script + ";"); } else { if (script.StartsWith("#!") == true) { // #! を // に置换 mStream = new StringStream("//" + Sharpen.Runtime.Substring(script, 2)); } else { mStream = new StringStream(script); } } if (CompileState.mEnableDicFuncQuickHack) { //----- dicfunc quick-hack mDicFunc = false; if (mIsExprMode && (script.StartsWith("[") == true || script.StartsWith("%[") == true)) { mDicFunc = true; } } //mIfLevel = 0; //mPrevPos = 0; //mNestLevel = 0; mIsFirst = true; //mRegularExpression = false; //mBareWord = false; PutValue(null); }
/// <summary>DaraArray の中の InterCodeGenerator を InterCodeObject に差し替える</summary> /// <param name="compiler"></param> public virtual void DateReplace(Compiler compiler) { int count = mInterCodeDataArea.Count; for (int i = 0; i < count; i++) { Variant d = mInterCodeDataArea[i]; object o = d.ToJavaObject(); if (o is InterCodeGenerator) { int idx = compiler.GetCodeIndex((InterCodeGenerator)o); if (idx < 0) { TJS.OutputToConsole("not found"); } d.Set(compiler.GetCodeObject(idx)); } } }
// update FunctionRegisterCodePoint /// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.TJSException"></exception> protected internal virtual void FinalizeObject() { if (mPropSetter != null) { mPropSetter = null; } if (mPropGetter != null) { mPropGetter = null; } if (mSuperClassGetter != null) { mSuperClassGetter = null; } if (mCodeArea != null) { mCodeArea = null; } if (mDataArea != null) { mDataArea.Clear(); mDataArea = null; } mBlock.Remove(this); if (mContextType != ContextType.TOP_LEVEL && mBlock != null) { mBlock = null; } mNamespace.Clear(); ClearNodesToDelete(); }
/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> public InterCodeGenerator(InterCodeGenerator parent, string name, Compiler block, int type) { //super(getContextHashSize(type)); //super.mCallFinalize = false; mNodeToDeleteVector = new VectorWrap<ExprNode>(); mCurrentNodeVector = new VectorWrap<ExprNode>(); mJumpList = new IntVector(); mNestVector = new VectorWrap<InterCodeGenerator.NestData>(); mArrayArgStack = new Stack<InterCodeGenerator.ArrayArg>(); mFuncArgStack = new Stack<InterCodeGenerator.FuncArg>(); mNamespace = new LocalNamespace(); mFixList = new AList<InterCodeGenerator.FixData>(); mNonLocalFunctionDeclVector = new VectorWrap<InterCodeGenerator.NonLocalFunctionDecl >(); mSuperClassGetterPointer = new IntVector(); mParent = parent; mPropGetter = mPropSetter = mSuperClassGetter = null; mCodeArea = new short[INC_ARRAY_COUNT]; mDataArea = new AList<Variant>(); mInterCodeDataArea = new AList<Variant>(); mFrameBase = 1; //mSuperClassExpr = null; //mMaxFrameCount = 0; //mMaxVariableCount = 0; //mFuncDeclArgCount = 0; //mFuncDeclUnnamedArgArrayBase = 0; mFuncDeclCollapseBase = -1; //mFunctionRegisterCodePoint = 0; mPrevSourcePos = -1; //mSourcePosArraySorted = false; //mSourcePosArray = null; if (name != null && name.Length > 0) { mName = name; } //else { // mName = null; //} //mAsGlobalContextMode = false; mContextType = type; switch (mContextType) { case ContextType.TOP_LEVEL: { // decide variable reservation count with context type mVariableReserveCount = 2; break; } case ContextType.FUNCTION: { mVariableReserveCount = 2; break; } case ContextType.EXPR_FUNCTION: { mVariableReserveCount = 2; break; } case ContextType.PROPERTY: { mVariableReserveCount = 0; break; } case ContextType.PROPERTY_SETTER: { mVariableReserveCount = 2; break; } case ContextType.PROPERTY_GETTER: { mVariableReserveCount = 2; break; } case ContextType.CLASS: { mVariableReserveCount = 2; break; } case ContextType.SUPER_CLASS_GETTER: { mVariableReserveCount = 2; break; } } mBlock = block; mBlock.Add(this); if (mContextType == ContextType.CLASS) { // add class information to the class instance information if (mMaxFrameCount < 1) { mMaxFrameCount = 1; } int dp = PutData(new Variant(mName)); int lexPos = GetLexPos(); // const %1, name // addci %-1, %1 // cl %1 if ((mCodeAreaPos + 7) >= mCodeArea.Length) { ExpandCodeArea(); } if (CompileState.mEnableDebugCode) { PutSrcPos(lexPos); } mCodeArea[mCodeAreaPos] = (short)VM_CONST; mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)1; mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)dp; mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)VM_ADDCI; mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)-1; mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)1; mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)VM_CL; mCodeAreaPos++; mCodeArea[mCodeAreaPos] = (short)1; mCodeAreaPos++; // update FunctionRegisterCodePoint mFunctionRegisterCodePoint = mCodeAreaPos; } }
// VMCodes // SubType // FuncArgType // result needed // condition flag needed // true logic // inverted logic /// <summary>バイトコードを出力する</summary> /// <returns></returns> public virtual ByteBuffer ExportByteCode(Compiler block, ConstArrayData constarray ) { int parent = -1; if (mParent != null) { parent = block.GetCodeIndex(mParent); } int propSetter = -1; if (mPropSetter != null) { propSetter = block.GetCodeIndex(mPropSetter); } int propGetter = -1; if (mPropGetter != null) { propGetter = block.GetCodeIndex(mPropGetter); } int superClassGetter = -1; if (mSuperClassGetter != null) { superClassGetter = block.GetCodeIndex(mSuperClassGetter); } int name = -1; if (mName != null) { name = constarray.PutString(mName); } // 13 * 4 データ部分のサイズ //int srcpossize = mSourcePosArray != null ? mSourcePosArray.position() * 8 : 0; // mSourcePosArray は配列の方がいいかな, codepos, sorcepos の顺で、int型で登录した方がいいかも int srcpossize = 0; // 主にデバッグ用の情报なので出力抑止 int codesize = (mCode.Length % 2) == 1 ? mCode.Length * 2 + 2 : mCode.Length * 2; int datasize = mDataArray.Length * 4; int scgpsize = mSuperClassGetterPointer != null ? mSuperClassGetterPointer.Size() * 4 : 0; int propsize = (mProperties != null ? mProperties.Count * 8 : 0) + 4; int size = 12 * 4 + srcpossize + codesize + datasize + scgpsize + propsize + 4 * 4; ByteBuffer result = ByteBuffer.Allocate(size); result.Order(ByteOrder.LITTLE_ENDIAN); result.Clear(); IntBuffer buf = result.AsIntBuffer(); buf.Clear(); buf.Put(parent); buf.Put(name); buf.Put(mContextType); buf.Put(mMaxVariableCount); buf.Put(mVariableReserveCount); buf.Put(mMaxFrameCount); buf.Put(mFuncDeclArgCount); buf.Put(mFuncDeclUnnamedArgArrayBase); buf.Put(mFuncDeclCollapseBase); buf.Put(propSetter); buf.Put(propGetter); buf.Put(superClassGetter); //int count = mSourcePosArray != null ? mSourcePosArray.position() : 0; int count = 0; buf.Put(count); // 主にデバッグ用の情报なので出力抑止 count = mCode.Length; buf.Put(count); ShortBuffer sbuf = result.AsShortBuffer(); sbuf.Clear(); sbuf.Position(buf.Position() * 2); sbuf.Put(mCode); if ((count % 2) == 1) { // アライメント sbuf.Put((short)0); } buf.Position(sbuf.Position() / 2); count = mDataArray.Length; buf.Put(count); sbuf.Position(buf.Position() * 2); for (int i = 0; i < count; i++) { Variant val = mDataArray[i]; short type = constarray.GetType(val); short v = (short)constarray.PutVariant(val, block); sbuf.Put(type); sbuf.Put(v); } buf.Position(sbuf.Position() / 2); count = mSuperClassGetterPointer != null ? mSuperClassGetterPointer.Size() : 0; buf.Put(count); for (int i_1 = 0; i_1 < count; i_1++) { int v = mSuperClassGetterPointer.Get(i_1); buf.Put(v); } count = 0; if (mProperties != null) { count = mProperties.Count; buf.Put(count); if (count > 0) { for (int i_2 = 0; i_2 < count; i_2++) { InterCodeGenerator.Property prop = mProperties[i_2]; // .Value.dumpClassStructure(nest+1); int propname = constarray.PutString(prop.Name); int propobj = -1; if (prop.Value != null) { propobj = block.GetCodeIndex(prop.Value); } buf.Put(propname); buf.Put(propobj); } } } else { buf.Put(count); } result.Limit(result.Capacity()); result.Position(0); return result; }
public int PutVariant(Variant v, Compiler block) { object o = v.ToJavaObject(); int type = GetType(v); switch (type) { case TYPE_VOID: { return 0; } case TYPE_OBJECT: { // 常に0 VariantClosure clo = (VariantClosure)o; if (clo.mObject == null && clo.mObjThis == null) { return 0; } else { // null の VariantClosure は受け入れる return -1; } goto case TYPE_INTER_OBJECT; } case TYPE_INTER_OBJECT: { // その他は入れない。Dictionary と Array は保存できるようにした方がいいが…… VariantClosure clo = (VariantClosure)o; Dispatch2 dsp = clo.mObject; return block.GetObjectIndex((InterCodeObject)dsp); } case TYPE_STRING: { return PutString(((string)o)); } case TYPE_OCTET: { return PutByteBuffer((ByteBuffer)o); } case TYPE_REAL: { return PutDouble(((Number)o)); } case TYPE_BYTE: { return PutByte(((Number)o)); } case TYPE_SHORT: { return PutShort(((Number)o)); } case TYPE_INTEGER: { return PutInteger(((Number)o)); } case TYPE_LONG: { return PutLong(((Number)o)); } case TYPE_INTER_GENERATOR: { return block.GetCodeIndex((InterCodeGenerator)o); } case TYPE_UNKNOWN: { return -1; } } return -1; }
/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.TJSException"></exception> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> public virtual void EvalExpression(string expression, Variant result, Dispatch2 context , string name, int lineofs) { // currently this works only with anonymous script blocks. // note that this function is basically the same as function above. if (name != null && name.Length > 0) { Compiler compiler = new Compiler(mOwner); compiler.SetName(name, lineofs); ScriptBlock blk = compiler.DoCompile(expression, true, result != null); compiler = null; if (blk != null) { blk.ExecuteTopLevel(result, context); if (blk.GetContextCount() == 0) { mOwner.RemoveScriptBlock(blk); } blk.Compact(); blk = null; } return; } // search through script block cache ScriptCache.ScriptCacheData data = new ScriptCache.ScriptCacheData(); data.mScript = expression; data.mExpressionMode = true; data.mMustReturnResult = result != null; ScriptBlock block = mCache.Get(data); if (block != null) { // found in cache // execute script block in cache block.ExecuteTopLevelScript(result, context); return; } // not found in cache Compiler compiler_1 = new Compiler(mOwner); compiler_1.SetName(name, lineofs); ScriptBlock blk_1 = compiler_1.DoCompile(expression, true, result != null); blk_1.ExecuteTopLevel(result, context); bool preprocess = compiler_1.IsUsingPreProcessor(); compiler_1 = null; //ScriptBlock blk = new ScriptBlock(mOwner); //blk.setText( result, expression, context, true); // add to cache if (blk_1.IsReusable() && !preprocess) { // currently only single-context script block is cached mCache.Put(data, blk_1); } else { if (blk_1.GetContextCount() == 0) { mOwner.RemoveScriptBlock(blk_1); } } blk_1.Compact(); blk_1 = null; return; }
/// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.TJSException"></exception> /// <exception cref="Kirikiri.Tjs2.CompileException"></exception> public virtual void ExecScript(string script, Variant result, Dispatch2 context, string name, int lineofs) { Compiler compiler = new Compiler(mOwner); if (name != null) { compiler.SetName(name, lineofs); } ScriptBlock blk = compiler.DoCompile(script, false, result != null); compiler = null; blk.ExecuteTopLevel(result, context); if (blk.GetContextCount() == 0) { mOwner.RemoveScriptBlock(blk); } blk.Compact(); blk = null; }
/// <exception cref="Kirikiri.Tjs2.CompileException"></exception> /// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.TJSException"></exception> public virtual void ToJavaCode(string script, string name, int lineofs, bool isresultneeded ) { Compiler compiler = new Compiler(this); if (name != null) { compiler.SetName(name, lineofs); } compiler.ToJavaCode(script, false, isresultneeded); compiler = null; }
public virtual void LexTest(string script) { Compiler compiler = new Compiler(this); int token = 0; int token1; ScriptLineData lineData = new ScriptLineData(script, 0); Lexer lexer = new Lexer(compiler, script, false, false); LexicalAnalyzer lex = new LexicalAnalyzer(compiler, script, false, false); try { do { token = lexer.GetNext(); token1 = lex.GetNext(); if (token1 != token) { int oleline = lineData.GetSrcPosToLine(lexer.GetCurrentPosition()); int newline = lineData.GetSrcPosToLine(lex.GetCurrentPosition()); System.Console.Out.Write("error line:" + oleline + ", " + newline + "\n"); } int v1 = lexer.GetValue(); int v2 = lex.GetValue(); if (v1 != v2) { int oleline = lineData.GetSrcPosToLine(lexer.GetCurrentPosition()); int newline = lineData.GetSrcPosToLine(lex.GetCurrentPosition()); System.Console.Out.Write("error line:" + oleline + ", " + newline + "\n"); } if (v1 != 0) { object o1 = lexer.GetValue(v1).ToJavaObject(); object o2 = lex.GetValue(v2).ToJavaObject(); if (!o1.Equals(o2)) { int oleline = lineData.GetSrcPosToLine(lexer.GetCurrentPosition()); int newline = lineData.GetSrcPosToLine(lex.GetCurrentPosition()); System.Console.Out.Write("o1:" + o1.ToString() + ", o2" + o2.ToString() + "\n"); System.Console.Out.Write("error line:" + oleline + ", " + newline + "\n"); } } } while (token != 0); } catch (CompileException) { } long start = Runtime.CurrentTimeMillis(); lexer = new Lexer(compiler, script, false, false); try { do { token = lexer.GetNext(); lexer.GetValue(); } while (token != 0); } catch (CompileException) { } long time = Runtime.CurrentTimeMillis() - start; System.Console.Out.Write("old lex : " + time + "ms\n"); start = Runtime.CurrentTimeMillis(); lex = new LexicalAnalyzer(compiler, script, false, false); try { do { token = lex.GetNext(); lex.GetValue(); } while (token != 0); } catch (CompileException) { } time = Runtime.CurrentTimeMillis() - start; System.Console.Out.Write("new lex : " + time + "ms\n"); }
/// <exception cref="Kirikiri.Tjs2.CompileException"></exception> /// <exception cref="Kirikiri.Tjs2.VariantException"></exception> /// <exception cref="Kirikiri.Tjs2.TJSException"></exception> public virtual void CompileScript(string script, string name, int lineofs, bool isresultneeded , BinaryStream output) { Compiler compiler = new Compiler(this); if (name != null) { compiler.SetName(name, lineofs); } compiler.Compile(script, false, isresultneeded, output); compiler = null; }