diff --git a/StgSharp.Script/Express/ExpNodeGenerator.OperatorParser.cs b/StgSharp.Script/Express/ExpNodeGenerator.OperatorParser.cs index f2111c3b..e31d8446 100644 --- a/StgSharp.Script/Express/ExpNodeGenerator.OperatorParser.cs +++ b/StgSharp.Script/Express/ExpNodeGenerator.OperatorParser.cs @@ -50,7 +50,76 @@ namespace StgSharp.Script.Express return leftPrecedence - rightPrecedence; } - public bool TryGenerateBinaryNode( Token t, out ExpNode node ) + public bool TryGenerateUnaryNode( Token t, out ExpNode node ) + { + ExpNode operand = GetNextOperandCache(); + switch( t.Value ) { + case ExpKeyword.UnaryPlus: + node = ExpUnaryOperatorNode.UnaryPlus( t, operand ); + return true; + case ExpKeyword.UnaryMinus: + node = ExpUnaryOperatorNode.UnaryMinus( t, operand ); + return true; + case ExpKeyword.Not: + node = ExpUnaryOperatorNode.UnaryNot( t, operand ); + return true; + default: + node = ExpNode.Empty; + return false; + } + } + + /// + /// WARNING: This method cannot process INDEXOF, FUNCTION CALLING, LOOP and any ENDING + /// SYMBOLS. + /// + private ExpNode ConvertOneOperator( Token op ) + { + switch( op.Flag ) { + case TokenFlag.Symbol_Unary: + TryGenerateUnaryNode( op, out ExpNode? node ); + _cache.PushOperand( node ); + return node; + case TokenFlag.Symbol_Binary: + TryGenerateBinaryNode( op, out node ); + _cache.PushOperand( node ); + return node; + case TokenFlag.Member: + if( _context.TryGetFunction( + op.Value, out ExpFunctionSource? f ) ) { + if( !_cache.PopOperand( out Token t, + out ExpNode? p ) ) { + node = ExpFunctionCallingNode.CallFunction( + op, f, p ); + return node; + } else { + throw new ExpCompileException( + t, + "An ExpNode for function calling is needed, but a token was popped" ); + } + } else if( ExpSchema.BuiltinSchema + .TryGetFunction( op.Value, out f ) ) { + if( !_cache.PopOperand( out Token t, + out ExpNode? p ) ) { + node = ExpFunctionCallingNode.CallFunction( + op, f, p ); + return node; + } else { + throw new ExpCompileException( + t, + "An ExpNode for function calling is needed, but a token was popped" ); + } + } else { + throw new NotImplementedException(); + + //uncertain case here + } + default: + throw new NotImplementedException(); + } + } + + private bool TryGenerateBinaryNode( Token t, out ExpNode node ) { ExpNode left = GetNextOperandCache(); ExpNode right = GetNextOperandCache(); @@ -85,71 +154,5 @@ namespace StgSharp.Script.Express } } - public bool TryGenerateUnaryNode( Token t, out ExpNode node ) - { - ExpNode operand = GetNextOperandCache(); - switch( t.Value ) { - case ExpKeyword.UnaryPlus: - node = ExpUnaryOperatorNode.UnaryPlus( t, operand ); - return true; - case ExpKeyword.UnaryMinus: - node = ExpUnaryOperatorNode.UnaryMinus( t, operand ); - return true; - case ExpKeyword.Not: - node = ExpUnaryOperatorNode.UnaryNot( t, operand ); - return true; - default: - node = ExpNode.Empty; - return false; - } - } - - /// - /// WARNING: This method cannot process INDEXOF, FUNCTION CALLING, LOOP and any ENDING - /// SYMBOLS. - /// - private void ConvertOneOperator() - { - Token @operator = _cache.PopOperator(); - - switch( @operator.Flag ) { - case TokenFlag.Symbol_Unary: - TryGenerateUnaryNode( @operator, out ExpNode? node ); - _cache.PushOperand( node ); - break; - case TokenFlag.Symbol_Binary: - TryGenerateBinaryNode( @operator, out node ); - _cache.PushOperand( node ); - break; - case TokenFlag.Member: - if( _context.TryGetFunction( - @operator.Value, out ExpFunctionSource? f ) ) { - if( !_cache.PopOperand( out Token t, - out ExpNode? p ) ) { - ExpFunctionCallingNode.CallFunction( - @operator, f, p ); - } else { - throw new ExpCompileException( - t, - "An ExpNode for function calling is needed, but a token was popped" ); - } - } else if( ExpSchema.BuiltinSchema - .TryGetFunction( @operator.Value, out f ) ) { - if( !_cache.PopOperand( out Token t, - out ExpNode? p ) ) { - ExpFunctionCallingNode.CallFunction( - @operator, f, p ); - } else { - throw new ExpCompileException( - t, - "An ExpNode for function calling is needed, but a token was popped" ); - } - } - break; - default: - break; - } - } - } } diff --git a/StgSharp.Script/Express/ExpNodeGenerator.PrefixReverseAnalysing.cs b/StgSharp.Script/Express/ExpNodeGenerator.PrefixReverseAnalysing.cs new file mode 100644 index 00000000..eaf6da4c --- /dev/null +++ b/StgSharp.Script/Express/ExpNodeGenerator.PrefixReverseAnalysing.cs @@ -0,0 +1,92 @@ +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +// file="ExpNodeGenerator.PrefixReverseAnalysing.cs" +// Project: StgSharp +// AuthorGroup: Nitload Space +// Copyright (c) Nitload Space. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and +// this permission notice shall be included in all copies +// or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, +// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH +// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using ExpKeyword = StgSharp.Script.Express.ExpCompile.KeyWord; + +namespace StgSharp.Script.Express +{ + public partial class ExpNodeGenerator + { + + private void ClosePrefixReverse( Token rightSeparator ) + { + Token op; + while( _cache.TryPopOperator( out op ) ) { + if( op.Value == ExpKeyword.Comma ) { + if( !_cache.TryPopOperand( + out bool isNode, out Token t1, out ExpNode? n1 ) ) { + throw new ExpCompileException( + op, "No expression before a comma" ); + } + if( !isNode ) { + //On some occasions, a token may found, + //but the processor is not implemented + throw new NotImplementedException(); + } + if( !_cache.TryPopOperand( + out isNode, out Token t2, out ExpNode? n2 ) ) { + throw new ExpCompileException( + op, "No expression before a comma" ); + } + if( !isNode ) { + //On some occasions, a token may found, + //but the processor is not implemented + throw new NotImplementedException(); + } + n1.PrependNode( n2 ); + _cache.PushOperand( n1 ); + continue; + } + ConvertOneOperator( op ); + + ExpNode node = GetNextOperandCache(); + _cache.PushOperand( node ); + } + if( !_cache.TryPopOperand( out _, out _, out ExpNode? root ) ) { + _cache.PushOperand( ExpNode.Empty ); + } + _cache.DecreaseDepth(); + if( IsSeparatorMatch( _cache.PeekOperator(), rightSeparator ) ) { + _cache.PopOperator(); + } else { + // some unexpected occasions + throw new NotImplementedException(); + } + } + + } +} diff --git a/StgSharp.Script/Express/ExpNodeGenerator.TokenSpliter.cs b/StgSharp.Script/Express/ExpNodeGenerator.TokenSpliter.cs index d7bf3b00..7796bf0f 100644 --- a/StgSharp.Script/Express/ExpNodeGenerator.TokenSpliter.cs +++ b/StgSharp.Script/Express/ExpNodeGenerator.TokenSpliter.cs @@ -41,14 +41,19 @@ namespace StgSharp.Script.Express public partial class ExpNodeGenerator { - private bool IsSeparatorMatch( Token source, Token target ) + private bool IsSeparatorMatch( + Token leftSperator, + Token rightSeparator ) { - return source.Value switch + return leftSperator.Value switch { - ExpKeyword.LeftBrace => target.Value == ExpKeyword.RightBrace, - ExpKeyword.LeftParen => target.Value == ExpKeyword.RightParen, - ExpKeyword.Comma => target.Value == ExpKeyword.Comma, - ExpKeyword.Semicolon => target.Value == ExpKeyword.Semicolon, + ExpKeyword.LeftBrace => rightSeparator.Value == + ExpKeyword.RightBrace, + ExpKeyword.LeftParen => rightSeparator.Value == + ExpKeyword.RightParen, + ExpKeyword.Comma => rightSeparator.Value == ExpKeyword.Comma, + ExpKeyword.Semicolon => rightSeparator.Value == + ExpKeyword.Semicolon, _ => false }; } @@ -76,9 +81,15 @@ namespace StgSharp.Script.Express } //reverse building + ClosePrefixReverse( t ); //make index node - _cache.PushOperand( ExpCollectionIndexNode.Create( t ) ); + _cache.PopOperand( out _, out ExpNode? expNode ); + if( !_cache.PopOperand( + out Token colleToken, out ExpNode? colleNode ) ) { } + _cache.PushOperand( + ExpCollectionIndexNode.Create( + t, ( colleNode as ExpCollectionInstanceBase )!, expNode ) ); return true; } @@ -128,7 +139,8 @@ namespace StgSharp.Script.Express _cache.PushOperand( t ); _cache.PushOperator( t ); } else { - ConvertOneOperator(); + ExpNode node = ConvertOneOperator( op ); + _cache.PushOperand( node ); goto processOperator; } } @@ -158,9 +170,7 @@ namespace StgSharp.Script.Express if( t.Flag != TokenFlag.Separator_Right ) { return false; } - - //convert all operator to node until meet a prefix separator - + ClosePrefixReverse( t ); return true; } @@ -173,11 +183,13 @@ namespace StgSharp.Script.Express int cmp = -1; processPrecedence: - Token tmp = _cache.PeekOperator(); - cmp = CompareOperatorPrecedence( t, tmp ); - if( cmp <= 0 ) { - ConvertOneOperator(); - goto processPrecedence; + if( _cache.TryPopOperator( out Token tmp ) ) { + cmp = CompareOperatorPrecedence( t, tmp ); + if( cmp <= 0 ) { + ExpNode node = ConvertOneOperator( tmp ); + _cache.PushOperand( node ); + goto processPrecedence; + } } _cache.PushOperand( t ); return true; diff --git a/StgSharp.Script/obj/x64/Debug/net8.0/StgSharp.Script.AssemblyInfo.cs b/StgSharp.Script/obj/x64/Debug/net8.0/StgSharp.Script.AssemblyInfo.cs index 5c6a2c48..d04f0ca8 100644 --- a/StgSharp.Script/obj/x64/Debug/net8.0/StgSharp.Script.AssemblyInfo.cs +++ b/StgSharp.Script/obj/x64/Debug/net8.0/StgSharp.Script.AssemblyInfo.cs @@ -14,7 +14,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("StgSharp.Script")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+6788bc4a0065508d7afa5f740da1b4ca6dd1efef")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+e73d2fd7fb4e601c32cee66e276f219fc9b4a377")] [assembly: System.Reflection.AssemblyProductAttribute("StgSharp.Script")] [assembly: System.Reflection.AssemblyTitleAttribute("StgSharp.Script")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/StgSharp.Script/obj/x64/Debug/net8.0/StgSharp.Script.sourcelink.json b/StgSharp.Script/obj/x64/Debug/net8.0/StgSharp.Script.sourcelink.json index 2eeaae6f..5e5a4d9d 100644 --- a/StgSharp.Script/obj/x64/Debug/net8.0/StgSharp.Script.sourcelink.json +++ b/StgSharp.Script/obj/x64/Debug/net8.0/StgSharp.Script.sourcelink.json @@ -1 +1 @@ -{"documents":{"D:\\NitloadIndustry\\研究项目\\1-Flagship\\TH2020\\ProjectFile\\内核源代码\\*":"https://raw.githubusercontent.com/Nitload-NSI/CCD_Github/6788bc4a0065508d7afa5f740da1b4ca6dd1efef/*"}} \ No newline at end of file +{"documents":{"D:\\NitloadIndustry\\研究项目\\1-Flagship\\TH2020\\ProjectFile\\内核源代码\\*":"https://raw.githubusercontent.com/Nitload-NSI/CCD_Github/e73d2fd7fb4e601c32cee66e276f219fc9b4a377/*"}} \ No newline at end of file