From 753cc167bc352df7a47cd17a1ea877666683f5f0 Mon Sep 17 00:00:00 2001 From: Nitload Date: Sat, 15 Mar 2025 09:24:30 +0800 Subject: [PATCH] Daily update on 20250315-092429 by Nitload Youmu. Additional Message : Arraging node generator struct, compile stat added. Signed-off-by: Nitload --- StgSharp.Script/Common/CompileStack.cs | 20 +- StgSharp.Script/Express/CompileEnv/KeyWord.cs | 142 ++++++++------ .../Express/ExpNodeGenerator.StateCommon.cs | 173 ++++++++++++++++++ .../ExpNodeGenerator.StateFunctionCalling.cs | 103 +++++++++++ StgSharp.Script/Express/ExpNodeGenerator.cs | 79 ++------ .../net8.0/StgSharp.Script.AssemblyInfo.cs | 2 +- 6 files changed, 394 insertions(+), 125 deletions(-) create mode 100644 StgSharp.Script/Express/ExpNodeGenerator.StateCommon.cs create mode 100644 StgSharp.Script/Express/ExpNodeGenerator.StateFunctionCalling.cs diff --git a/StgSharp.Script/Common/CompileStack.cs b/StgSharp.Script/Common/CompileStack.cs index dae8b978..fc497ac2 100644 --- a/StgSharp.Script/Common/CompileStack.cs +++ b/StgSharp.Script/Common/CompileStack.cs @@ -53,6 +53,11 @@ namespace StgSharp.Script private Stack _isNode = new Stack(); + public CompileDepthMark CurrentDepthMark + { + get => _depthStack.Peek(); + } + public int Depth => _depthStack.Count; public int OperandCount => _isNode.Count; @@ -74,13 +79,14 @@ namespace StgSharp.Script CompileDepthMark mark = _depthStack.Pop(); } - public CompileDepthMark IncreaseDepth() + public CompileDepthMark IncreaseDepth( int usage ) { CompileDepthMark mark = new CompileDepthMark { OperandBegin = OperandCount, - OperatorBegin = OperatorCount + OperatorBegin = OperatorCount, + State = usage }; _depthStack.Push( mark ); return mark; @@ -208,13 +214,19 @@ namespace StgSharp.Script public int OperandBegin { get; - set; + internal set; } public int OperatorBegin { get; - set; + internal set; + } + + public int State + { + get; + internal set; } } diff --git a/StgSharp.Script/Express/CompileEnv/KeyWord.cs b/StgSharp.Script/Express/CompileEnv/KeyWord.cs index 36a52973..4190b4f3 100644 --- a/StgSharp.Script/Express/CompileEnv/KeyWord.cs +++ b/StgSharp.Script/Express/CompileEnv/KeyWord.cs @@ -62,11 +62,11 @@ namespace StgSharp.Script.Express public static class KeyWord { - public static readonly HashSet ScopeBlock = new HashSet { + public static HashSet ScopeBlock = new HashSet { EndAlias, EndCase, EndConstant, EndEntity, EndFunction, EndIf, EndLocal, EndProcedure, EndRepeat, EndRule, EndSchema, EndSubtypeConstraint, EndType }; - public static readonly HashSet Symbols = [ + public static HashSet Symbols = [ Dot, Comma, Semicolon, Colon, Percent, Apostrophe, Backslash, IndexOf, RightBracket, LeftBrace, RightBrace, Pipe, LeftParen, RightParen, LeftAsterisk, @@ -74,6 +74,90 @@ namespace StgSharp.Script.Express CommentStart, CommentEnd, ColonEqualColon, ColonNotEqualColon ]; + public static HashSet DataTypes + { + get; + } = [ + Array, Bag, Binary, Boolean, Enumeration, Integer, List, Logical, Number, Of, Real, Set, String + ]; + + public static HashSet InternalProcess + { + get; + } = [ + Insert, Remove + ]; + + public static HashSet BuiltinFunctions + { + get; + } = [ + Abs, Acos, Asin, Atan, Blength, Cos, Exists, Exp, + Format, Hibound, Hiindex, Length, Lobound, Log, + Log2, Log10, Loindex, Nvl, Odd, Rolesof, Sin, + Sizeof, Sqrt, Tan, Typeof, Usedin, Value, + ValueIn, ValueUnique + ]; + + public static HashSet Literals + { + get; + } = [ + QuestionMark, Self, Const, E, Pi, False, True, Unknown + ]; + + public static HashSet Operators + { + get; + } = [ + And, AndOr, Div, In, Like, Mod, Not, Or, Xor, + Add, Sub, Mul, Slash, Equal, NotEqual, + LessThan, GreaterThan, LessThanOrEqual, GreaterThanOrEqual + ]; + + public static HashSet Aliasing + { + get; + } = [ + Alias, Renamed + ]; + + public static HashSet ModifiersAttributes + { + get; + } = [ + Abstract, Aggregate, As, BasedOn, By, Escape, Fixed, From, Use, With + ]; + + public static HashSet QueryReference + { + get; + } = [ + Query, Reference, Select + ]; + + public static HashSet ConstraintsInheritance + { + get; + } = [ + Oneof, Optional, Subtype, SubtypeConstraint, Supertype, TotalOver, Unique, Where + ]; + + public static HashSet Declarations + { + get; + } = [ + Constant, Derive, Entity, Extensible, Fixed, Function, Generic, + GenericEntity, Inverse, Local, Procedure, Rule, Schema, Type, Var + ]; + + public static HashSet FlowControl + { + get; + } = [ + Begin, Case, Else, End, For, If, Otherwise, Repeat, Return, Skip, Then, To, Until, While + ]; + #region Basic Data Type public const string Array = "ARRAY"; @@ -279,6 +363,7 @@ namespace StgSharp.Script.Express public const string LessThan = "<"; public const string GreaterThan = ">"; public const string IndexOf = "["; + public const string LeftBracket = "["; public const string RightBracket = "]"; public const string LeftBrace = "{"; public const string RightBrace = "}"; @@ -299,58 +384,7 @@ namespace StgSharp.Script.Express public const string ColonEqualColon = ":=:"; public const string ColonNotEqualColon = ":<>:"; - #endregion - - public static readonly HashSet DataTypes = [ - Array, Bag, Binary, Boolean, Enumeration, Integer, List, Logical, Number, Of, Real, Set, String - ]; - - public static readonly HashSet FlowControl = [ - Begin, Case, Else, End, For, If, Otherwise, Repeat, Return, Skip, Then, To, Until, While - ]; - - public static readonly HashSet Declarations = [ - Constant, Derive, Entity, Extensible, Fixed, Function, Generic, - GenericEntity, Inverse, Local, Procedure, Rule, Schema, Type, Var - ]; - - public static readonly HashSet ConstraintsInheritance = [ - Oneof, Optional, Subtype, SubtypeConstraint, Supertype, TotalOver, Unique, Where - ]; - - public static readonly HashSet QueryReference = [ - Query, Reference, Select - ]; - - public static readonly HashSet ModifiersAttributes = [ - Abstract, Aggregate, As, BasedOn, By, Escape, Fixed, From, Use, With - ]; - - public static readonly HashSet Aliasing = [ - Alias, Renamed - ]; - public static readonly HashSet Operators = [ - And, AndOr, Div, In, Like, Mod, Not, Or, Xor, - Add, Sub, Mul, Slash, Equal, NotEqual, - LessThan, GreaterThan, LessThanOrEqual, GreaterThanOrEqual - ]; - - public static readonly HashSet Literals = [ - QuestionMark, Self, Const, E, Pi, False, True, Unknown - ]; - - public static readonly HashSet InternalFunctions = [ - Abs, Acos, Asin, Atan, Blength, Cos, Exists, Exp, - Format, Hibound, Hiindex, Length, Lobound, Log, - Log2, Log10, Loindex, Nvl, Odd, Rolesof, Sin, - Sizeof, Sqrt, Tan, Typeof, Usedin, Value, - ValueIn, ValueUnique - ]; - - public static readonly HashSet InternalProcess = [ - Insert, Remove - ]; - + #endregion } } diff --git a/StgSharp.Script/Express/ExpNodeGenerator.StateCommon.cs b/StgSharp.Script/Express/ExpNodeGenerator.StateCommon.cs new file mode 100644 index 00000000..de323e5a --- /dev/null +++ b/StgSharp.Script/Express/ExpNodeGenerator.StateCommon.cs @@ -0,0 +1,173 @@ +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +// file="ExpNodeGenerator.StateCommon.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.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 AppendToken_Common( Token t ) + { + switch( t.Flag ) { + // operand, check precedence and push + case TokenFlag.Symbol_Unary or TokenFlag.Symbol_Binary: + int cmp = -1; + processPrecedence: + Token tmp = _cache.PeekOperator(); + cmp = CompareOperatorPrecedence( t, tmp ); + if( cmp <= 0 ) { + ConvertOneOperator(); + goto processPrecedence; + } + _cache.PushOperand( t ); + break; + + // literal, construct and push + case TokenFlag.Number or TokenFlag.String: + _cache.PushOperand( t ); + break; + + // instance ref, make ref and push + // function call, push as operator + // keyword, call TryParseConstant method to process + // name of member in instance, parse as MemberNameNode + case TokenFlag.Member: + if( _context.TryGetFunction( t.Value, out _ ) ) { + _cache.PushOperator( t ); + } else if( _local.TryGetMember( t.Value, + out ExpNode? node ) ) { + if( node is ExpElementInstanceBase instance ) { + _cache.PushOperand( instance.MakeReference( t ) ); + return;// ref of an instance + } + } else if( TryParseConstant( t ) ) { + return; + } else if( TryParseFunction( t ) ) { + return; + } else if( TryParseBranch( t ) ) { + return; + } else { + _cache.PushOperand( t ); + } + break; + case TokenFlag.Separator_Single: //a , ; found + // if operator stack is not empty, convert all operators to node until meet a same separator + // or OperandAheadOfSeparator property is less than certain value + _cache.PushOperator( t ); + break; + case TokenFlag.Separator_Left: //a ( [ { found + // check if the last token is a function name, loop block or branch + _cache.PushOperator( t ); + break; + case TokenFlag.Separator_Right: //a } ] ) found + //Convert operator until meet a matched separator + while( _cache.TryPopOperator( out Token op ) ) { + if( IsSeparatorMatch( t, op ) ) { + return; + } else { } + } + + break; + case TokenFlag.Index_Left: // a [ found + break; + case TokenFlag.Index_Right: // a ] found + break; + default: + break; + } + } + + private bool IsSeparatorMatch( Token source, Token target ) + { + return source.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, + _ => false + }; + } + + private bool TryParseBranch( Token t ) + { + if( t.Value == ExpKeyWord.Case ) { + _cache.PushOperator( t ); + _cache.IncreaseDepth( ( int )StateCode.CaseBranch ); + return true; + } else if( t.Value == ExpKeyWord.If ) { + _cache.PushOperator( t ); + _cache.IncreaseDepth( ( int )StateCode.IfBranch ); + return true; + } else if( t.Value == ExpKeyWord.Repeat ) { + _cache.PushOperator( t ); + _cache.IncreaseDepth( ( int )StateCode.RepeatLoop ); + return true; + } + return false; + } + + private bool TryParseConstant( Token t ) + { + if( t.Value == ExpKeyWord.True ) { + _cache.PushOperand( new ExpBoolNode( t, true ) ); + return true; + } else if( t.Value == ExpKeyWord.False ) { + _cache.PushOperand( new ExpBoolNode( t, false ) ); + return true; + } + return false; + } + + private bool TryParseFunction( Token t ) + { + if( ExpKeyWord.BuiltinFunctions.Contains( t.Value ) ) { + _cache.PushOperator( t ); + _cache.IncreaseDepth( ( int )StateCode.FunctionCalling ); + return true; + } else if( _context.TryGetFunction( + t.Value, out ExpFunctionSource? f ) ) { + _cache.PushOperand( t ); + _cache.IncreaseDepth( ( int )StateCode.FunctionCalling ); + return true; + } + return false; + } + + } +} diff --git a/StgSharp.Script/Express/ExpNodeGenerator.StateFunctionCalling.cs b/StgSharp.Script/Express/ExpNodeGenerator.StateFunctionCalling.cs new file mode 100644 index 00000000..6952443f --- /dev/null +++ b/StgSharp.Script/Express/ExpNodeGenerator.StateFunctionCalling.cs @@ -0,0 +1,103 @@ +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +// file="ExpNodeGenerator.StateFunctionCalling.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.Linq; +using System.Text; +using System.Threading.Tasks; + +using static StgSharp.Script.Express.ExpCompile; + +namespace StgSharp.Script.Express +{ + public partial class ExpNodeGenerator + { + + private bool _isCallingFunction = false; + private List _funcCallDepthCount = new List( + ); + + private void EnterFunctionCalling() + { + _isCallingFunction = true; + CompileDepthMark mark = _cache.IncreaseDepth( + ( int )StateCode.FunctionCalling ); + _funcCallDepthCount.Add( mark ); + } + + private void ExitFunctionCalling() + { + CompileDepthMark mark = _funcCallDepthCount.Last(); + if( _funcCallDepthCount.Count == 0 ) { + _isCallingFunction = false; + } + } + + //checking _operandAheadOfDepth can be used to check if the function calling has no param. + //put one of param to tail of function calling pram expression node + /// + /// Compile a parameter expression and add it to head of function parameter node list. + /// + private void MergeFunctionCallingParameter( Token currentSeparator ) + { + if( _cache.OperandAheadOfDepth == 1 ) { + if( _cache.PopOperand( out Token t, out ExpNode? n ) ) { + n!.PrependNode( ExpNode.NonOperation( currentSeparator ) ); + } else { + switch( t.Flag ) { + case TokenFlag.Number: + if( int.TryParse( t.Value, out int intVal ) ) { + n = new ExpIntNode( t, intVal ); + } else if( float.TryParse( + t.Value, out float floatVal ) ) { + n = new ExpRealNumberNode( t, floatVal ); + } + break; + case TokenFlag.String: + n = new ExpStringNode( t, t.Value ); + break; + case TokenFlag.Member: + + // case1: name of a _instance, make ref copy + // case2: name of a function, make a function call + // case3: unknown, make a _instance member node, check while link + break; + default: + break; + } + } + } else { + //TODO compile the param expression + } + } + + } +} diff --git a/StgSharp.Script/Express/ExpNodeGenerator.cs b/StgSharp.Script/Express/ExpNodeGenerator.cs index 099fc87e..2b1b7af4 100644 --- a/StgSharp.Script/Express/ExpNodeGenerator.cs +++ b/StgSharp.Script/Express/ExpNodeGenerator.cs @@ -68,63 +68,7 @@ namespace StgSharp.Script.Express /// public void AppendToken( Token expToken ) { - switch( expToken.Flag ) { - // operand, check precedence and push - case TokenFlag.Symbol_Unary or TokenFlag.Symbol_Binary: - int cmp = -1; - processPrecedence: - Token tmp = _cache.PeekOperator(); - cmp = CompareOperatorPrecedence( expToken, tmp ); - if( cmp <= 0 ) { - ConvertOneOperator(); - goto processPrecedence; - } - _cache.PushOperand( expToken ); - break; - - // literal, construxt and ppush - case TokenFlag.Number or TokenFlag.String: - _cache.PushOperand( expToken ); - break; - - // instance ref, make ref and push - // function call, push as operator - // keyword, call TryParseKeyWord method to process - // name of member in instance, parse as MemberNameNode - case TokenFlag.Member: - if( _context.TryGetFunction( expToken.Value, out _ ) ) { - _cache.PushOperator( expToken ); - } else if( _local.TryGetMember( - expToken.Value, out ExpNode? node ) ) { - if( node is ExpElementInstanceBase instance ) { - _cache.PushOperand( - instance.MakeReference( expToken ) ); - return; // ref of an instance - } - } else if( TryParseKeyWord( expToken ) ) { - return; - } else { - _cache.PushOperand( - new ExpElementMemberNameNode( expToken ) ); - } - break; - case TokenFlag.Separator_Single: //a , ; found - // if operator stack is not empty, convert all operators to node until meet a same separator - // or OperandAheadOfSeparator property is less than certain value - _cache.PushOperator( expToken ); - break; - case TokenFlag.Separator_Left: //a ( [ { found - // check if the last token is a function name, loop block or branch - // then increase depth - _cache.PushOperator( expToken ); - break; - case TokenFlag.Separator_Right: //a } ] ) found - //Close current depth and cache call node in this depth as a partial AST - break; - case TokenFlag.Index_Left: // a [ found - break; - case TokenFlag.Index_Right: // a ] found - break; + switch( _cache.CurrentDepthMark.State ) { default: break; } @@ -161,17 +105,20 @@ namespace StgSharp.Script.Express } } - private bool TryParseKeyWord( Token t ) + /**/ + + public enum StateCode { - if( t.Value == ExpKeyWord.True ) { - _cache.PushOperand( new ExpBoolNode( t, true ) ); - return true; - } else if( t.Value == ExpKeyWord.False ) { - _cache.PushOperand( new ExpBoolNode( t, false ) ); - return true; - } else if( ExpCompile.LetterIsKeyword( t.Value ) ) { } + + Common, + FunctionCalling, + ForLoop, + RepeatLoop, + UntilLoop, + IfBranch, + CaseBranch, + } - /**/ } } 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 48db1393..1dd5d2d4 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+6222f8c8be57d511d2ec40523717e20b87fcff9d")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+9307d7d658b6a03e1e26a2b4111589dd77c3597d")] [assembly: System.Reflection.AssemblyProductAttribute("StgSharp.Script")] [assembly: System.Reflection.AssemblyTitleAttribute("StgSharp.Script")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]