diff --git a/StgSharp.Script/Express/ExpAstNode/ExpLiteralNode.cs b/StgSharp.Script/Express/ExpAstNode/ExpLiteralNode.cs index 5d627030..45a5044c 100644 --- a/StgSharp.Script/Express/ExpAstNode/ExpLiteralNode.cs +++ b/StgSharp.Script/Express/ExpAstNode/ExpLiteralNode.cs @@ -113,6 +113,17 @@ namespace StgSharp.Script.Express public override string TypeName => EqualityTypeConvert.Name; + public static ExpBoolNode False( Token? t ) + { + return new( t ?? new Token( "FALSE", 0, -1, TokenFlag.Member ), false, + isLiteral: true ); + } + + public static ExpBoolNode True( Token? t ) + { + return new( t ?? new Token( "TRUE", 0, -1, TokenFlag.Member ), true, isLiteral: true ); + } + } public class ExpRealNumberNode : ExpElementInstance diff --git a/StgSharp.Script/Express/ExpAstNode/ExpRepeatNode.cs b/StgSharp.Script/Express/ExpAstNode/ExpRepeatNode.cs index e06ece26..8ddfab33 100644 --- a/StgSharp.Script/Express/ExpAstNode/ExpRepeatNode.cs +++ b/StgSharp.Script/Express/ExpAstNode/ExpRepeatNode.cs @@ -33,6 +33,7 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Text; +using System.Threading.Channels; namespace StgSharp.Script.Express { @@ -44,46 +45,13 @@ namespace StgSharp.Script.Express internal ExpRepeatNode( Token source, - ExpNode operationBegin, - ExpElementInstance variable, - ExpNode begin, - ExpNode end ) - : base( source ) - { - ExpNode increment; - switch( ( ExpNodeFlag )variable.NodeFlag | ExpNodeFlag.BuiltinType_Any ) - { - case ExpNodeFlag.BuiltinType_Real: - increment = new ExpRealNumberNode( - new Token( - ExpressCompile.PoolString( "1.0f" ), source.Line, -1, - TokenFlag.Number ), - 1.0f, isLiteral: true ); - break; - case ExpNodeFlag.BuiltinType_Int: - increment = new ExpIntNode( - new Token( - ExpressCompile.PoolString( "1" ), source.Line, -1, TokenFlag.Number ), - 1, isLiteral: true ); - break; - default: - throw new ExpInvalidTypeException( "Int or Real", "otherwise" ); - } - _begin = begin; - _variable = variable; - _end = end; - _increment = increment; - _nodeFlag = ExpNodeFlag.Branch_Repeat; - _operationBegin = operationBegin; - } - - internal ExpRepeatNode( - Token source, - ExpNode operationBegin, ExpElementInstance variable, ExpNode begin, ExpNode end, - ExpNode increment ) + ExpNode increment, + ExpNode operationBegin, + ExpNode untilRule, + ExpNode whileRule ) : base( source ) { if( variable.NodeFlag != begin.NodeFlag || begin.NodeFlag != end.NodeFlag || ( increment != @@ -91,13 +59,35 @@ namespace StgSharp.Script.Express increment.NodeFlag ) ) { throw new InvalidCastException(); } - ArgumentNullException.ThrowIfNull( increment ); - _begin = begin; + if( ExpNode.IsNullOrEmpty( increment ) ) + { + switch( ( ExpNodeFlag )variable.NodeFlag | ExpNodeFlag.BuiltinType_Any ) + { + case ExpNodeFlag.BuiltinType_Real: + increment = new ExpRealNumberNode( + new Token( + ExpressCompile.PoolString( "1.0f" ), source.Line, -1, + TokenFlag.Number ), + 1.0f, isLiteral: true ); + break; + case ExpNodeFlag.BuiltinType_Int: + increment = new ExpIntNode( + new Token( + ExpressCompile.PoolString( "1" ), source.Line, -1, + TokenFlag.Number ), + 1, isLiteral: true ); + break; + default: + throw new ExpInvalidTypeException( "Int or Real", "otherwise" ); + } + } _variable = variable; + _begin = begin; _end = end; _increment = increment; - _nodeFlag = ExpNodeFlag.Branch_Repeat; _operationBegin = operationBegin; + _untilRule = untilRule; + _whileRule = whileRule; } public override ExpNode Left => throw new NotImplementedException(); @@ -111,45 +101,40 @@ namespace StgSharp.Script.Express _operationBegin.AppendNode( node ); } - public static ExpRepeatNode Create( - Token t, - ExpElementInstance repeatVariable, - ExpNode begin, - ExpNode end, - ExpNode repeatBody ) - { - string typename = repeatVariable.NodeFlag.ToString(); - ExpRepeatNode ret = new ExpRepeatNode( t, repeatBody, repeatVariable, begin, end, null ) - { - /* - * 0 increment variable type - * 1: variable name - * 2: beginning value - * 3: ending value - * 4: increment - * 5: body - */ - CodeConvertTemplate = $$""" - for({{0}} {{1}} = {{2}}; {{1}} <= {{3}}; {{1}} += {{4}}) - { - {{5}} - } - """ - }; - return ret; - } - + /// + /// Create an AST node for repeat expression in EXPRESS language. The loop does not has + /// WHILE and UNTIL regulation. + /// + /// + /// Position of the loop + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// public static ExpRepeatNode Create( Token t, ExpElementInstance repeatVariable, ExpNode begin, ExpNode end, ExpNode increment, - ExpNode whileRule, - ExpNode untilRule, ExpNode body ) { - ExpRepeatNode ret = new ExpRepeatNode( t, body, repeatVariable, begin, end, increment ) + ExpNode untilRule = ExpBoolNode.False( null ); + ExpNode whileRule = ExpBoolNode.True( null ); + ExpRepeatNode ret = new ExpRepeatNode( + t, repeatVariable, begin, end, increment, body, whileRule, untilRule ) { /* * 0 increment variable type @@ -166,7 +151,44 @@ namespace StgSharp.Script.Express { if(!( {{6}} )) break; {{5}} - if(!( {{7}} )) break; + if( {{7}} ) break; + } + """ + }; + return ret; + } + + public static ExpRepeatNode Create( + Token t, + ExpElementInstance repeatVariable, + ExpNode begin, + ExpNode end, + ExpNode increment, + ExpNode whileRule, + ExpNode untilRule, + ExpNode body ) + { + whileRule = IsNullOrEmpty( whileRule ) ? ExpBoolNode.True( t ) : whileRule; + untilRule = IsNullOrEmpty( untilRule ) ? ExpBoolNode.False( t ) : untilRule; + ExpRepeatNode ret = new ExpRepeatNode( + t, repeatVariable, begin, end, increment, body, whileRule, untilRule ) + { + /* + * 0 increment variable type + * 1: variable name + * 2: beginning value + * 3: ending value + * 4: increment + * 5: body + * 6: while + * 7: until + */ + CodeConvertTemplate = $$""" + for({{0}} {{1}} = {{2}}; {{1}} <= {{3}}; {{1}} += {{4}}) + { + if(!( {{6}} )) break; + {{5}} + if( {{7}} ) break; } """ }; diff --git a/StgSharp.Script/Express/ExpSourceReader.cs b/StgSharp.Script/Express/ExpSourceReader.cs index 8d977a77..a359ec7f 100644 --- a/StgSharp.Script/Express/ExpSourceReader.cs +++ b/StgSharp.Script/Express/ExpSourceReader.cs @@ -356,7 +356,7 @@ namespace StgSharp.Script.Express private static partial Regex GetNextWordTokenPattern(); [GeneratedRegex( - @"(?-?\s*?[0-9]+(?:\.[0-9]*)?)(?\s*?)(?\S|$)", + @"(?-?\s*?[0-9]+(?:\.[0-9]*)?E?(?:[+-]?[0-9]+))(?\s*?)(?\S|$)", RegexOptions.Singleline )] private static partial Regex GetNumberLiteralPattern(); diff --git a/StgSharp.Script/Express/ExpSyntaxAnalyzer.RepeatLoop.cs b/StgSharp.Script/Express/ExpSyntaxAnalyzer.RepeatLoop.cs index f4ced073..6047f84a 100644 --- a/StgSharp.Script/Express/ExpSyntaxAnalyzer.RepeatLoop.cs +++ b/StgSharp.Script/Express/ExpSyntaxAnalyzer.RepeatLoop.cs @@ -87,9 +87,11 @@ namespace StgSharp.Script.Express state.Body = root; _cache.DecreaseDepth(); root = ExpRepeatNode.Create( - state.Position, state.Body, state.Begin, state.End, state.IncrementVariable, - state.UntilExpression, state.WhileExpression ); + state.Position, state.IncrementVariable, state.Begin, state.End, + state.IncrementVariable, state.Body, state.UntilExpression, state.WhileExpression ); _cache.StatementsInDepth.Push( root ); + _tempVariableInLoops.Remove( state.IncrementVariable.CodeConvertTemplate ); + return true; } private bool TryParseRepeatBeginning( RepeatLoopState state, Token t ) @@ -156,7 +158,7 @@ namespace StgSharp.Script.Express ConvertAndPushOneOperator( op ); } _cache.PopOperand( out _, out ExpNode? root ); - state.IncrementVariable = root; + state.StepIncrement = root; return true; } @@ -192,6 +194,9 @@ namespace StgSharp.Script.Express return true; case ExpKeyword.Assignment: state.CurrentState = ExpKeyword.Assignment; + _tempVariableInLoops.Add( + state.IncrementVariable.CodeConvertTemplate, state.IncrementVariable ); + return true; default: if( ExpTypeSource.IsNullOrVoid( state.IncrementVariableType ) ) @@ -231,9 +236,13 @@ namespace StgSharp.Script.Express public RepeatLoopState( Token t ) { Position = t; + UntilExpression = ExpNode.Empty; + WhileExpression = ExpNode.Empty; } - public ExpNode IncrementVariable { get; set; } + public ExpElementInstance IncrementVariable { get; set; } + + public ExpNode StepIncrement { get; set; } public ExpNode Begin { get; set; }