From 54d50e25fc6446f77256e0e47b2dca3765eea3fa Mon Sep 17 00:00:00 2001
From: Arc <87562566+Arc-huangjingtong@users.noreply.github.com>
Date: Tue, 13 Aug 2024 17:44:24 +0800
Subject: [PATCH] Update
---
.../UniInkSpeed/NUnit_UniInkSpeed.cs | 81 +++---
Arc.UniInk/Arc.UniInk.sln.DotSettings.user | 20 +-
Arc.UniInk/Arc.UniInk/UniInk_Extensions.cs | 241 ++++++++++--------
Arc.UniInk/Arc.UniInk/UniInk_Speed.cs | 12 +-
4 files changed, 197 insertions(+), 157 deletions(-)
diff --git a/Arc.UniInk/Arc.UniInk.Benchmark/UniInkSpeed/NUnit_UniInkSpeed.cs b/Arc.UniInk/Arc.UniInk.Benchmark/UniInkSpeed/NUnit_UniInkSpeed.cs
index 5719a53..723f09f 100644
--- a/Arc.UniInk/Arc.UniInk.Benchmark/UniInkSpeed/NUnit_UniInkSpeed.cs
+++ b/Arc.UniInk/Arc.UniInk.Benchmark/UniInkSpeed/NUnit_UniInkSpeed.cs
@@ -16,6 +16,7 @@
using Arc.UniInk;
using System;
using System.Collections.Generic;
+ using JetBrains.Util;
using NUnit.Framework;
@@ -377,31 +378,49 @@ public static void Test_Temp()
/////////////////////////////////////////////// Extension Test ////////////////////////////////////////////////
- // [Repeat(10)]
- // [TestCase(" if( 1 > 2 ) "
- // + " { "
- // + " 123 "
- // + " } "
- // + " else "
- // + " { "
- // + " 456 "
- // + " } ")]
- // /////////////////////////////////////
- // [TestCase(" if( 1 > 2 ) "
- // + " { "
- // + " 123 "
- // + " } "
- // + " else if (3>6) "
- // + " { "
- // + " 456 "
- // + " } "
- // + " else "
- // + " { "
- // + " 666 "
- // + " } ")]
+ //[Repeat(1)]
+ ///////////////////////////////////////
+ [TestCase(" if ( 1 > 2 ) "
+ + " { "
+ + " 123 "
+ + " } "
+ + " else "
+ + " { "
+ + " return 456 "
+ + " } ")]
+ ///////////////////////////////////////
+ [TestCase(" if ( 1 > 2 ) "
+ + " { "
+ + " 123 "
+ + " } "
+ + " else if ( 3 > 6 ) "
+ + " { "
+ + " 456 "
+ + " } "
+ + " else "
+ + " { "
+ + " return 666 "
+ + " } ")]
+ ///////////////////////////////////////
+ [TestCase(" if ( 1 > 2 ) "
+ + " { "
+ + " 123 "
+ + " } "
+ + " else if ( 3 > 6 ) "
+ + " { "
+ + " 456 "
+ + " } "
+ + " else if ( 3 < 6 ) "
+ + " { "
+ + " return 456 "
+ + " } "
+ + " else "
+ + " { "
+ + " return 666 "
+ + " } ")]
public static void Test_Expression_IfStatements(string input)
{
- var test = Ink.Evaluate(input);
+ var test = Ink.Evaluate_IfStatement(input);
if (test is InkValue value)
{
Console.WriteLine(value.Value_int); // each time , the result will be different
@@ -410,22 +429,6 @@ public static void Test_Expression_IfStatements(string input)
}
}
- [TestCase("((((((()()()()()))))))")]
- [TestCase("()")]
- [TestCase("()()")]
- [TestCase("(())(())")]
- public static void Temp_Function_GetMatchOperator(string input)
- {
- var keys = Ink.CompileLexerAndFill(input, 0, input.Length - 1);
-
- Console.WriteLine(keys.Count);
-
- var res = UniInk_Speed.GetMatchOperator(keys, InkOperator.ParenthisLeft, InkOperator.ParenthisRight, 0, keys.Count - 1);
-
- Console.WriteLine(res.StartIndex);
- Console.WriteLine(res.EndIndex);
- }
-
/////////////////////////////////////////////// Helper Object ////////////////////////////////////////////////
diff --git a/Arc.UniInk/Arc.UniInk.sln.DotSettings.user b/Arc.UniInk/Arc.UniInk.sln.DotSettings.user
index 181f3ca..0e1697c 100644
--- a/Arc.UniInk/Arc.UniInk.sln.DotSettings.user
+++ b/Arc.UniInk/Arc.UniInk.sln.DotSettings.user
@@ -15,14 +15,26 @@
<Assembly Path="F:\UniInk-CSharpInterpreter4AOT\Arc.UniInk\packages\BenchmarkDotNet.Annotations.0.13.12\lib\netstandard2.0\BenchmarkDotNet.Annotations.dll" />
</AssemblyExplorer>
True
- <SessionState ContinuousTestingMode="0" IsActive="True" Name="Test_Expression_IfStatements" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
+ <SessionState ContinuousTestingMode="0" IsActive="True" Name="Test_Expression_IfStatements" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
<TestAncestor>
- <TestId>NUnit3x::1BA70864-1706-44D0-9D58-669FD5703A14::.NETFramework,Version=v4.8::Arc.UniInk.NUnitTest.NUnit_UniInkSpeed.Test_Arithmetic_Float</TestId>
- <TestId>NUnit3x::1BA70864-1706-44D0-9D58-669FD5703A14::.NETFramework,Version=v4.8::Arc.UniInk.NUnitTest.NUnit_UniInkSpeed.Test_Arithmetic_Int("9*((1+(2+3)*(4+5))+6+7)")</TestId>
- <TestId>NUnit3x::1BA70864-1706-44D0-9D58-669FD5703A14::.NETFramework,Version=v4.8::Arc.UniInk.NUnitTest.NUnit_UniInkSpeed.Test_Arithmetic_Int</TestId>
+ <TestId>NUnit3x::1BA70864-1706-44D0-9D58-669FD5703A14::.NETFramework,Version=v4.8::Arc.UniInk.NUnitTest.NUnit_UniInkSpeed.Test_Expression_IfStatements</TestId>
</TestAncestor>
</SessionState>
+ <SessionState ContinuousTestingMode="0" Name="Test_Expression_IfStatements #3" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
+ <TestAncestor>
+ <TestId>NUnit3x::1BA70864-1706-44D0-9D58-669FD5703A14::.NETFramework,Version=v4.8::Arc.UniInk.NUnitTest.NUnit_UniInkSpeed.Test_Expression_IfStatements</TestId>
+ </TestAncestor>
+</SessionState>
+ <SessionState ContinuousTestingMode="0" Name="Test_Expression_IfStatements #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
+ <TestAncestor>
+ <TestId>NUnit3x::1BA70864-1706-44D0-9D58-669FD5703A14::.NETFramework,Version=v4.8::Arc.UniInk.NUnitTest.NUnit_UniInkSpeed.Test_Expression_IfStatements</TestId>
+ </TestAncestor>
+</SessionState>
+
+
+
+
diff --git a/Arc.UniInk/Arc.UniInk/UniInk_Extensions.cs b/Arc.UniInk/Arc.UniInk/UniInk_Extensions.cs
index c3711dd..7d5177e 100644
--- a/Arc.UniInk/Arc.UniInk/UniInk_Extensions.cs
+++ b/Arc.UniInk/Arc.UniInk/UniInk_Extensions.cs
@@ -1,7 +1,6 @@
namespace Arc.UniInk
{
- using System;
using System.Text.RegularExpressions;
@@ -13,47 +12,6 @@
/*******************************************************************************************************************/
- /// Provide commonly tools in
- /// not assurance zero GC
- public static class UniInk_Extensions
- {
- #region Remove comments
-
-
- //Base on : https://stackoverflow.com/questions/3524317/regex-to-strip-line-comments-from-c-sharp/3524689#3524689
- private static readonly Regex removeCommentsRegex = new($"{blockComments}|{lineComments}|{stringsIgnore}|{verbatimStringsIgnore}", RegexOptions.Singleline | RegexOptions.Compiled);
- private static readonly Regex newLineCharsRegex = new(@"\r\n|\r|\n", RegexOptions.Compiled);
-
- private const string verbatimStringsIgnore = @"@(""[^""]*"")+"; //language=regex
- private const string stringsIgnore = @"""((\\[^\n]|[^""\n])*)"""; //language=regex
- private const string blockComments = @"/\*(.*?)\*/"; //language=regex
- private const string lineComments = @"//[^\r\n]*"; //language=regex
-
-
- /// Remove all line and block comments from the specified C# script
- /// C# script without comments
- /// C# script with comments
- public static string RemoveComments(string scriptWithComments)
- {
- return removeCommentsRegex.Replace(scriptWithComments, Evaluator);
-
- string Evaluator(Match match)
- {
- if (match.Value.StartsWith("/"))
- {
- var newLineCharsMatch = newLineCharsRegex.Match(match.Value);
-
- return match.Value.StartsWith("/*") && newLineCharsMatch.Success ? newLineCharsMatch.Value : " ";
- }
-
- return match.Value;
- }
- }
-
-
- #endregion
- }
-
#region Support for UniInk_Speed : If Statement
@@ -64,41 +22,56 @@ public partial class UniInk_Speed
/// Not support Nested if statement
protected static object ProcessList_ScriptsWithIfStatement(InkSyntaxList keys)
{
- var start = 0;
- var end = keys.Count - 1;
- object res;
+ var index_start = 0;
+ var index_end = keys.Count - 1;
+ object res = null;
while (true)
{
//找到第一个[if]
- var (success_if, index_if) = FindOperator(keys, InkOperator.KeyIf, start, end);
+ var (success_if, index_if) = FindOperator(keys, InkOperator.KeyIf, index_start, index_end);
//找到第一个[ ;]
- var (success_semi, index_semi) = FindOperator(keys, InkOperator.Semicolon, start, end);
+ var (success_semi, index_semi) = FindOperator(keys, InkOperator.Semicolon, index_start, index_end);
if (success_semi && index_semi < index_if)
{
- ProcessList(keys, start, index_semi - 1);
+ ProcessList(keys, index_start, index_semi - 1);
keys.SetDirty(index_semi);
- start = index_semi + 1;
+ index_start = index_semi + 1;
continue;
}
if (success_if && index_if < index_semi)
{
- ProcessList_IfStatement(keys, index_if);
+ var current = ProcessList_IfStatement(keys, index_if);
+
+ keys.SetDirty(null, index_start, current);
+ index_start = current + 1;
continue;
}
-
- res = ProcessList(keys, start, index_semi); //index is the last index
+ if (index_start < index_end)
+ {
+ res = ProcessList(keys, index_start, index_semi); //index is the last index
+ }
break;
}
+ for (var i = 0 ; i < keys.Count ; i++)
+ {
+ if (keys.CastOther[i] is InkValue { returner: true } value)
+ {
+ res = value.Clone();
+ }
+ }
+
return res;
}
+ /// Process the if statement
+ /// Return the processed lasted operator [}]
protected static int ProcessList_IfStatement(InkSyntaxList keys, int start)
{
// Begin : keyword [if] (condition) { operation } Open : [if] flag
@@ -106,6 +79,8 @@ protected static int ProcessList_IfStatement(InkSyntaxList keys, int start)
// End : keyword [else] { operation } need : [if] flag and close [if] flag
// 这个函数会被检测函数调用,那么一开始一定有一个 If 关键字
+
+ // 定位 If(condition) 条件的开始和结束
var (conditionStart, conditionEnd)
= GetMatchOperator(keys, InkOperator.ParenthisLeft, InkOperator.ParenthisRight, start, keys.Count - 1);
@@ -116,7 +91,7 @@ protected static int ProcessList_IfStatement(InkSyntaxList keys, int start)
}
- // 定位操作的开始和结束
+ // 定位If(condition){ operation } 操作的开始和结束
var (operationStart, operationEnd)
= GetMatchOperator(keys, InkOperator.BraceLeft, InkOperator.BraceRight, conditionEnd + 1, keys.Count - 1);
@@ -129,6 +104,7 @@ protected static int ProcessList_IfStatement(InkSyntaxList keys, int start)
var flag_result = false;
var ifCondition = false;
var currentEnd = operationEnd;
+ var index_end = keys.Count - 1;
// 计算条件
@@ -141,18 +117,14 @@ protected static int ProcessList_IfStatement(InkSyntaxList keys, int start)
ifCondition = true;
ProcessList(keys, operationStart + 1, operationEnd - 1);
}
- else
- {
- ifCondition = false;
- }
}
while (true)
{
// Check the position relationship between the next else and if, and then enumerate all cases based on their relationship (very elegant)
- var (success_else, index_else) = FindOperator(keys, InkOperator.KeyElse, operationEnd + 1, keys.Count - 1);
- var (success_if, index_if) = FindOperator(keys, InkOperator.KeyIf, operationEnd + 1, keys.Count - 1);
+ var (success_else, index_else) = FindOperator(keys, InkOperator.KeyElse, currentEnd + 1, index_end);
+ var (success_if, index_if) = FindOperator(keys, InkOperator.KeyIf, currentEnd + 1, index_end);
// 1. 如果没有找到 else 和 if , 直接退出If 结算 , 说明后面再也没有 If 语句了 , 交给下一个循环即可
// 2. 如果找到了 if , 没找到 else , 说明这是一个 if 语句 , 交给下一个循环即可
@@ -162,20 +134,26 @@ protected static int ProcessList_IfStatement(InkSyntaxList keys, int start)
switch (success_else, success_if, index_if - index_else)
{
- case (false, false, _) : return operationEnd;
- case (false, true, _) : return operationEnd;
+ case (false, false, _) : return currentEnd;
+ case (false, true, _) : return currentEnd;
case (true, false, _) :
case (true, true, > 1) :
{
+ var temp_start = index_else + 1;
+
+ if (success_if) temp_start++;
+
var (opElseStart, opElseEnd)
- = GetMatchOperator(keys, InkOperator.BraceLeft, InkOperator.BraceRight, index_else + 1, keys.Count - 1);
+ = GetMatchOperator(keys, InkOperator.BraceLeft, InkOperator.BraceRight, temp_start, keys.Count - 1);
if (!ifCondition)
{
ProcessList(keys, opElseStart + 1, opElseEnd - 1);
}
- return opElseEnd;
+ currentEnd = opElseEnd;
+
+ return currentEnd;
}
case (true, true, 1) : // else if
{
@@ -194,75 +172,120 @@ protected static int ProcessList_IfStatement(InkSyntaxList keys, int start)
//FuncA();
//FuncB();
- // 匹配 else if 后的条件
+ // 匹配 else if (condition) 后的条件
var (cdsStart, cdsEnd)
- = GetMatchOperator(keys, InkOperator.ParenthisLeft, InkOperator.ParenthisRight, index_if + 1, keys.Count - 1);
+ = GetMatchOperator(keys, InkOperator.ParenthisLeft, InkOperator.ParenthisRight, index_if + 1, index_end);
// 计算 else if 条件后的操作
var (opElseStart, opElseEnd)
- = GetMatchOperator(keys, InkOperator.BraceLeft, InkOperator.BraceRight, cdsEnd + 1, keys.Count - 1);
+ = GetMatchOperator(keys, InkOperator.BraceLeft, InkOperator.BraceRight, cdsEnd + 1, index_end);
- if (!ifCondition) //如果还没有找到正确的条件
- {
- // 计算 else if 后的条件
- var condition_elseif = ProcessList(keys, cdsStart + 1, cdsEnd - 1);
- if (condition_elseif is InkValue conditionValue_elseif)
- {
- ifCondition = conditionValue_elseif;
- }
+ // 计算 else if 后的条件
+ var condition_elseif = ProcessList(keys, cdsStart + 1, cdsEnd - 1);
- if (!ifCondition)
+ if (condition_elseif is InkValue conditionValue_elseif)
+ {
+ if (conditionValue_elseif && ifCondition == false)
{
ProcessList(keys, opElseStart + 1, opElseEnd - 1);
}
- }
+ ifCondition = conditionValue_elseif || ifCondition;
+ }
+ currentEnd = opElseEnd;
break;
}
}
}
}
+ /// Judge the input String is a Script or not (depend on the operator:[;] [{])
+ protected static bool InputIsScript_IfStatement(InkSyntaxList keys)
+ {
+ foreach (var obj in keys.ObjectList)
+ {
+ //match [;] or [{]
+ if (obj is InkOperator op && (Equals(op, InkOperator.Semicolon) || Equals(op, InkOperator.BraceLeft)))
+ {
+ return true;
+ }
+ }
+
+
+ return false;
+ }
+
+ public static object ExecuteProcess_IfStatement(InkSyntaxList keys)
+ {
+ var res = InputIsScript_IfStatement(keys) ? ProcessList_ScriptsWithIfStatement(keys) : ProcessList(keys, 0, keys.Count - 1);
+
+ return res;
+ }
+ /// Evaluate the expression with the if statement
+ public object Evaluate_IfStatement(string expression, int startIndex, int endIndex)
+ {
+ var keys = CompileLexerAndFill(expression, startIndex, endIndex);
+
+ var result = ExecuteProcess_IfStatement(keys);
- // the sign of an if statement:
- // Begin : keyword [if] (condition) { operation }
- // Then : keyword [else if] (condition) { operation } need : [if]
- // End : keyword [else] { operation } need : [if] and close [if]
-
-
-
- // if (Has State Keywords)
- // {
- //
- //
- //
- // While (true)
- // {
- // var (hasState , ConditionPartStart , ConditionPartEnd , OperationStart , OperationEnd) = GetStatementPart();
- // var result = ProcessList(keys, OperationStart, OperationEnd);
- // if (hasState == false)
- // {
- // break;
- // }
- // else if (result == true)
- // {
- //
- // ProcessList(keys, OperationStart, OperationEnd); (recursion)
- // var end = GetStatementEnd(); // get the end of the statement , and jump to ;
- // SetDirty(..end);
- // }
- // else
- // {
- // continue;
- // }
- // }
- // }
+ RecoverResources(keys);
+
+ return result;
+ }
+
+ public object Evaluate_IfStatement(string expression)
+ {
+ return Evaluate_IfStatement(expression, 0, expression.Length - 1);
+ }
}
#endregion
+
+
+ /// Provide commonly tools in
+ /// not assurance zero GC
+ public static class UniInk_Extensions
+ {
+ #region Remove comments
+
+
+ //Base on : https://stackoverflow.com/questions/3524317/regex-to-strip-line-comments-from-c-sharp/3524689#3524689
+ private static readonly Regex removeCommentsRegex = new($"{blockComments}|{lineComments}|{stringsIgnore}|{verbatimStringsIgnore}", RegexOptions.Singleline | RegexOptions.Compiled);
+ private static readonly Regex newLineCharsRegex = new(@"\r\n|\r|\n", RegexOptions.Compiled);
+
+ private const string verbatimStringsIgnore = @"@(""[^""]*"")+"; //language=regex
+ private const string stringsIgnore = @"""((\\[^\n]|[^""\n])*)"""; //language=regex
+ private const string blockComments = @"/\*(.*?)\*/"; //language=regex
+ private const string lineComments = @"//[^\r\n]*"; //language=regex
+
+
+ /// Remove all line and block comments from the specified C# script
+ /// C# script without comments
+ /// C# script with comments
+ public static string RemoveComments(string scriptWithComments)
+ {
+ return removeCommentsRegex.Replace(scriptWithComments, Evaluator);
+
+ string Evaluator(Match match)
+ {
+ if (match.Value.StartsWith("/"))
+ {
+ var newLineCharsMatch = newLineCharsRegex.Match(match.Value);
+
+ return match.Value.StartsWith("/*") && newLineCharsMatch.Success ? newLineCharsMatch.Value : " ";
+ }
+
+ return match.Value;
+ }
+ }
+
+
+ #endregion
+ }
+
}
\ No newline at end of file
diff --git a/Arc.UniInk/Arc.UniInk/UniInk_Speed.cs b/Arc.UniInk/Arc.UniInk/UniInk_Speed.cs
index e5150d2..1629eb3 100644
--- a/Arc.UniInk/Arc.UniInk/UniInk_Speed.cs
+++ b/Arc.UniInk/Arc.UniInk/UniInk_Speed.cs
@@ -978,7 +978,7 @@ protected static (bool result, int startIndex, int endIndex) FindSection(InkSynt
}
/// Find the outermost operator range in the specified left and right
- public static (int StartIndex, int EndIndex) GetMatchOperator(InkSyntaxList keys, InkOperator opLeft, InkOperator opRight, int start, int end)
+ protected static (int StartIndex, int EndIndex) GetMatchOperator(InkSyntaxList keys, InkOperator opLeft, InkOperator opRight, int start, int end)
{
int startIndex = -1, balance = -1;
@@ -1107,8 +1107,8 @@ protected static bool InputIsScript(InkSyntaxList keys)
{
foreach (var obj in keys.ObjectList)
{
- //match [;] or [{]
- if (obj is InkOperator @operator && (Equals(@operator, InkOperator.Semicolon) || Equals(@operator, InkOperator.BraceLeft)))
+ //match [;]
+ if (obj is InkOperator @operator && Equals(@operator, InkOperator.Semicolon))
{
return true;
}
@@ -1442,6 +1442,7 @@ public static object InkOperator_Return(object left, object right)
{
case InkValue rightValue :
{
+ rightValue.Calculate();
var result = rightValue.Clone();
result.returner = true;
return result;
@@ -1579,6 +1580,9 @@ public static void Release(InkValue value)
value.Value_Meta.Clear();
value.isCalculate = false;
+ value.setter = false;
+ value.getter = false;
+ value.returner = false;
pool.Enqueue(value);
}
@@ -2072,8 +2076,6 @@ public static void Recover(InkSyntaxList value)
public readonly List