Daily update on 20250407-000601 by Nitload Youmu. Additional Message : Repeat block analyzer complete, need unit test. collection processor, builtin function, procedure caller and element source parser will be implemented

Signed-off-by: Nitload <YoumuLiu_NSI@whv0t.onmicrosoft.com>
This commit is contained in:
Nitload
2025-04-07 00:06:01 +08:00
parent c8f426d2e8
commit d270b6b1f8
4 changed files with 119 additions and 77 deletions
@@ -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
@@ -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;
}
/// <summary>
/// Create an AST node for repeat expression in EXPRESS language. The loop does not has
/// WHILE and UNTIL regulation.
/// </summary>
/// <param name="t">
/// Position of the loop
/// </param>
/// <param name="repeatVariable">
///
/// </param>
/// <param name="begin">
///
/// </param>
/// <param name="end">
///
/// </param>
/// <param name="repeatBody">
///
/// </param>
/// <returns>
///
/// </returns>
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;
}
"""
};
+1 -1
View File
@@ -356,7 +356,7 @@ namespace StgSharp.Script.Express
private static partial Regex GetNextWordTokenPattern();
[GeneratedRegex(
@"(?<token>-?\s*?[0-9]+(?:\.[0-9]*)?)(?<end>\s*?)(?<rest>\S|$)",
@"(?<token>-?\s*?[0-9]+(?:\.[0-9]*)?E?(?:[+-]?[0-9]+))(?<end>\s*?)(?<rest>\S|$)",
RegexOptions.Singleline )]
private static partial Regex GetNumberLiteralPattern();
@@ -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; }