Daily update on 20250328-131548 by Nitload Youmu. Additional Message : IF branch can be full functionally compiled. Next will be CASE_OF branch
Signed-off-by: Nitload <YoumuLiu_NSI@whv0t.onmicrosoft.com>
This commit is contained in:
@@ -14,7 +14,7 @@ using System.Reflection;
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("StgSharp.Model")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+ffd5825a051f04f4105ac5ed02e754176ce6f608")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+36b6ad5a526ca6ef66d826f614e8476a99fe52f7")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("StgSharp.Model")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("StgSharp.Model")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"documents":{"D:\\NitloadIndustry\\研究项目\\1-Flagship\\TH2020\\ProjectFile\\内核源代码\\*":"https://raw.githubusercontent.com/Nitload-NSI/CCD_Github/ffd5825a051f04f4105ac5ed02e754176ce6f608/*"}}
|
||||
{"documents":{"D:\\NitloadIndustry\\研究项目\\1-Flagship\\TH2020\\ProjectFile\\内核源代码\\*":"https://raw.githubusercontent.com/Nitload-NSI/CCD_Github/36b6ad5a526ca6ef66d826f614e8476a99fe52f7/*"}}
|
||||
@@ -30,6 +30,7 @@
|
||||
//-----------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@@ -41,23 +42,27 @@ namespace StgSharp.Script
|
||||
public class CompileDepthMark
|
||||
{
|
||||
|
||||
public CompileDepthMark( int operatorBegin, int operandBegin, int usage )
|
||||
{
|
||||
OperatorBegin = operatorBegin;
|
||||
OperandBegin = operandBegin;
|
||||
}
|
||||
|
||||
public CompileDepthMark(
|
||||
int operatorBegin,
|
||||
int operandBegin,
|
||||
int usage,
|
||||
ICompileDepthState stateCache )
|
||||
internal CompileDepthMark( int operatorBegin, int operandBegin, int usage )
|
||||
{
|
||||
OperatorBegin = operatorBegin;
|
||||
OperandBegin = operandBegin;
|
||||
Usage = usage;
|
||||
}
|
||||
|
||||
internal CompileDepthMark(
|
||||
int operatorBegin,
|
||||
int operandBegin,
|
||||
int usage,
|
||||
ICompileDepthState stateCache )
|
||||
{
|
||||
OperatorBegin = operatorBegin;
|
||||
OperandBegin = operandBegin;
|
||||
Usage = usage;
|
||||
StateCache = stateCache;
|
||||
}
|
||||
|
||||
public bool IsBeginOfBlock { get; internal set; }
|
||||
|
||||
public ICompileDepthState StateCache { get; internal set; }
|
||||
|
||||
public int OperandBegin { get; internal set; }
|
||||
|
||||
@@ -50,10 +50,12 @@ namespace StgSharp.Script
|
||||
private Stack<CompileDepthMark> _depthStack = new Stack<CompileDepthMark>();
|
||||
|
||||
private Stack<bool> _isNode = new Stack<bool>();
|
||||
private Stack<Stack<TNode>> _statementCache = new Stack<Stack<TNode>>();
|
||||
|
||||
public CompileStack()
|
||||
{
|
||||
_depthStack.Push( new CompileDepthMark( 0, 0, 0 ) );
|
||||
_depthStack.Push( new CompileDepthMark( 0, 0, 0, null! ) );
|
||||
_statementCache.Push( new Stack<TNode>() );
|
||||
}
|
||||
|
||||
public CompileDepthMark CurrentDepthMark
|
||||
@@ -77,19 +79,39 @@ namespace StgSharp.Script
|
||||
get => OperandCount - _depthStack.Peek().OperandBegin;
|
||||
}
|
||||
|
||||
public Stack<TNode> StatementsInDepth
|
||||
{
|
||||
get => _statementCache.Peek();
|
||||
}
|
||||
|
||||
public void DecreaseDepth()
|
||||
{
|
||||
CompileDepthMark mark = _depthStack.Pop();
|
||||
Stack<TNode> statementsInDepth = _statementCache.Pop();
|
||||
}
|
||||
|
||||
public CompileDepthMark IncreaseDepth( int usage )
|
||||
{
|
||||
CompileDepthMark mark =
|
||||
new CompileDepthMark( OperatorCount, OperandCount, usage );
|
||||
|
||||
_depthStack.Push( mark );
|
||||
_statementCache.Push( new Stack<TNode>() );
|
||||
return mark;
|
||||
}
|
||||
|
||||
public TNode PackAllStatements()
|
||||
{
|
||||
if( StatementsInDepth.Count == 0 ) {
|
||||
return TNode.Empty;
|
||||
}
|
||||
TNode first = StatementsInDepth.Peek();
|
||||
while( StatementsInDepth.Count > 0 ) {
|
||||
first.PrependNode( StatementsInDepth.Pop() );
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
public bool PeekOperand( out Token t, out TNode n )
|
||||
{
|
||||
if( OperandAheadOfDepth <= 0 )
|
||||
|
||||
@@ -43,24 +43,39 @@ namespace StgSharp.Script.Express
|
||||
private ExpNode _rule;
|
||||
private ExpNode _trueOpBegin ;
|
||||
|
||||
public ExpIfNode( Token source, ExpNode rule, ExpNode trueOpBegin )
|
||||
: base( source )
|
||||
{
|
||||
_rule = rule;
|
||||
_trueOpBegin = trueOpBegin;
|
||||
CodeConvertTemplate = ExpressCompile.PoolString(
|
||||
"""
|
||||
if ( {0} )
|
||||
{
|
||||
{1}
|
||||
}
|
||||
""" );
|
||||
}
|
||||
|
||||
public ExpIfNode(
|
||||
Token source,
|
||||
ExpSchema context,
|
||||
ExpNode rule,
|
||||
ExpNode rootOperationIfTrue,
|
||||
ExpNode rootOperationIfFalse )
|
||||
Token source,
|
||||
ExpNode rule,
|
||||
ExpNode rootOperationIfTrue,
|
||||
ExpNode rootOperationIfFalse )
|
||||
: base( source )
|
||||
{
|
||||
_rule = rule;
|
||||
_trueOpBegin = rootOperationIfFalse;
|
||||
_falseOpBegin = rootOperationIfFalse;
|
||||
CodeConvertTemplate = """
|
||||
if( {0} ) {
|
||||
CodeConvertTemplate = ExpressCompile.PoolString(
|
||||
"""
|
||||
if( {0} )
|
||||
{
|
||||
{1}
|
||||
} else {
|
||||
{2}
|
||||
}
|
||||
""";
|
||||
""" );
|
||||
}
|
||||
|
||||
public override ExpNode Left => _trueOpBegin;
|
||||
|
||||
@@ -54,7 +54,8 @@ namespace StgSharp.Script.Express
|
||||
_nextStringLiteralPattern = GetStringLiteralPattern(),
|
||||
_nextNumberLiteralPattern = GetNumberLiteralPattern(),
|
||||
_nextStringLiteralPatternWithSingle = GetStringLiteralPatternWithSingle(),
|
||||
_skipBlankPattern = GetSkipBlankPattern();
|
||||
_skipBlankPattern = GetSkipBlankPattern(),
|
||||
_nextSymbolPattern = GetSymbolPattern();
|
||||
private string _lineCache;
|
||||
private Token _last;
|
||||
|
||||
@@ -76,20 +77,14 @@ namespace StgSharp.Script.Express
|
||||
get => _provider.Location;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Read code until end of a line. Lines in multi-line comment will be ignored. Line
|
||||
/// begins with part of multi-line comment will automatically remove the comment part,
|
||||
/// but beginning with a full multi-line comment will not causing removing.</para> <para>
|
||||
/// (*Just Like The Comment Here*) Will Not Be Removed </para>
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
///
|
||||
/// </returns>
|
||||
public unsafe ReadOnlySpan<char> ReadLine()
|
||||
{
|
||||
bool lineOver = string.IsNullOrEmpty( _lineCache ) || _current >= _lineCache.Length;
|
||||
while( lineOver || _isReadingMultiLineComment )
|
||||
{
|
||||
if( IsEmpty ) {
|
||||
return ReadOnlySpan<char>.Empty;
|
||||
}
|
||||
if( lineOver )
|
||||
{
|
||||
do
|
||||
@@ -123,7 +118,10 @@ namespace StgSharp.Script.Express
|
||||
{
|
||||
int begin, end, rest;
|
||||
readLine:
|
||||
ReadOnlySpan<char> source = ReadLine();
|
||||
ReadOnlySpan<char> source;
|
||||
if( !TryReadLine( out source ) ) {
|
||||
return Token.Empty;
|
||||
}
|
||||
char c = source[ 0 ];
|
||||
|
||||
if( char.IsLetter( c ) )
|
||||
@@ -131,9 +129,6 @@ namespace StgSharp.Script.Express
|
||||
Match match = _nextWordTokenPattern.Match( _lineCache, _current );
|
||||
if( match.Success )
|
||||
{
|
||||
if( match.Groups[ EndMark ].Index >= _lineCache.Length ) {
|
||||
throw new ExpStringNotCloseException( _lineNum );
|
||||
}
|
||||
begin = match.Groups[ TokenMark ].Index;
|
||||
end = match.Groups[ EndMark ].Index;
|
||||
rest = match.Groups[ RestMark ].Index;
|
||||
@@ -230,63 +225,83 @@ namespace StgSharp.Script.Express
|
||||
{
|
||||
begin = _current;
|
||||
_current++;
|
||||
if( _last.Flag != TokenFlag.Member )
|
||||
{
|
||||
_last = new(
|
||||
ExpressCompile.PoolString( source[ ..1 ] ), _lineNum, begin,
|
||||
TokenFlag.Symbol_Unary );
|
||||
} else
|
||||
if( _last.Flag == TokenFlag.Member || _last.Flag ==
|
||||
TokenFlag.Index_Right || _last.Flag == TokenFlag.Separator_Right )
|
||||
{
|
||||
_last = new(
|
||||
ExpressCompile.PoolString( source[ ..1 ] ), _lineNum, begin,
|
||||
TokenFlag.Symbol_Binary );
|
||||
} else
|
||||
{
|
||||
_last = new(
|
||||
ExpressCompile.PoolString( source[ ..1 ] ), _lineNum, begin,
|
||||
TokenFlag.Symbol_Unary );
|
||||
}
|
||||
return _last;
|
||||
}
|
||||
case '{':
|
||||
begin = _current;
|
||||
_current++;
|
||||
return new Token(
|
||||
_last = new Token(
|
||||
ExpressCompile.PoolString( "{" ), _lineNum, begin,
|
||||
TokenFlag.Separator_Left );
|
||||
return _last;
|
||||
case '[':
|
||||
begin = _current;
|
||||
_current++;
|
||||
return new Token(
|
||||
_last = new Token(
|
||||
ExpressCompile.PoolString( "[" ), _lineNum, begin,
|
||||
TokenFlag.Index_Left );
|
||||
return _last;
|
||||
case ']':
|
||||
begin = _current;
|
||||
_current++;
|
||||
return new Token(
|
||||
_last = new Token(
|
||||
ExpressCompile.PoolString( "]" ), _lineNum, begin,
|
||||
TokenFlag.Index_Right );
|
||||
return _last;
|
||||
case ';' or ',':
|
||||
begin = _current;
|
||||
_current++;
|
||||
return new Token(
|
||||
_last = new Token(
|
||||
ExpressCompile.PoolString( source[ ..1 ] ), _lineNum, begin,
|
||||
TokenFlag.Separator_Middle );
|
||||
return _last;
|
||||
case ':':
|
||||
if( source[ 1 ] == '=' )
|
||||
match = _nextSymbolPattern.Match( _lineCache, _current );
|
||||
begin = match.Groups[ TokenMark ].Index;
|
||||
end = match.Groups[ EndMark ].Index;
|
||||
rest = match.Groups[ RestMark ].Index;
|
||||
_current = rest;
|
||||
if( end - begin == 1 )
|
||||
{
|
||||
begin = _current;
|
||||
_current += 2;
|
||||
return new Token(
|
||||
ExpressCompile.Keyword.Assignment, _lineNum, begin,
|
||||
TokenFlag.Symbol_Binary );
|
||||
_last = new Token(
|
||||
ExpressCompile.Keyword.Colon, _lineNum, begin,
|
||||
TokenFlag.Separator_Middle );
|
||||
} else
|
||||
{
|
||||
_last = new Token(
|
||||
ExpressCompile.PoolString( source[ ..( end - begin ) ] ), _lineNum,
|
||||
begin, TokenFlag.Symbol_Binary );
|
||||
}
|
||||
begin = _current;
|
||||
_current++;
|
||||
return new Token(
|
||||
ExpressCompile.Keyword.Colon, _lineNum, begin,
|
||||
TokenFlag.Separator_Middle );
|
||||
return _last;
|
||||
case '+' or '/' or '\\' or '*' or '.':
|
||||
match = _nextSymbolPattern.Match( _lineCache, _current );
|
||||
begin = match.Groups[ TokenMark ].Index;
|
||||
end = match.Groups[ EndMark ].Index;
|
||||
rest = match.Groups[ RestMark ].Index;
|
||||
_current = rest;
|
||||
_last = new Token(
|
||||
ExpressCompile.PoolString( source[ ..( end - begin ) ] ), _lineNum,
|
||||
begin, TokenFlag.Symbol_Binary );
|
||||
return _last;
|
||||
case '=':
|
||||
begin = _current;
|
||||
_current++;
|
||||
return new(
|
||||
ExpressCompile.PoolString( source[ ..1 ] ), _lineNum, begin,
|
||||
_last = new Token(
|
||||
ExpressCompile.Keyword.Equal, _lineNum, begin,
|
||||
TokenFlag.Symbol_Binary );
|
||||
return _last;
|
||||
default:
|
||||
throw new ExpInvalidCharException( c );
|
||||
}
|
||||
@@ -323,15 +338,16 @@ namespace StgSharp.Script.Express
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryReadLine( out ReadOnlySpan<char> line )
|
||||
{
|
||||
line = ReadLine();
|
||||
return line != ReadOnlySpan<char>.Empty;
|
||||
}
|
||||
|
||||
public bool TryReadToken( out Token t )
|
||||
{
|
||||
if( IsEmpty )
|
||||
{
|
||||
t = Token.Empty;
|
||||
return false;
|
||||
}
|
||||
t = ReadToken();
|
||||
return true;
|
||||
return !IsEmpty;
|
||||
}
|
||||
|
||||
[GeneratedRegex(
|
||||
@@ -357,5 +373,10 @@ namespace StgSharp.Script.Express
|
||||
RegexOptions.Singleline )]
|
||||
private static partial Regex GetStringLiteralPatternWithSingle();
|
||||
|
||||
[GeneratedRegex(
|
||||
@"(?<token>[:<>=+\-*\/]+)(?<end>\s?)\s*?(?<rest>\S|$)",
|
||||
RegexOptions.Singleline )]
|
||||
private static partial Regex GetSymbolPattern();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="ExpSyntaxAnalyzer.DepthEnter.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 Microsoft.CodeAnalysis.Diagnostics;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ExpKeyword = StgSharp.Script.Express.ExpressCompile.Keyword;
|
||||
|
||||
namespace StgSharp.Script.Express
|
||||
{
|
||||
public partial class ExpSyntaxAnalyzer
|
||||
{
|
||||
|
||||
internal void AttemptEnterNewDepth( Token t )
|
||||
{
|
||||
switch( t.Value )
|
||||
{
|
||||
case ExpKeyword.If:
|
||||
_cache.IncreaseDepth( ( int )ExpCompileStateCode.IfBranch );
|
||||
return;
|
||||
case ExpKeyword.Case:
|
||||
_cache.IncreaseDepth( ( int )ExpCompileStateCode.CaseBranch );
|
||||
return;
|
||||
case ExpKeyword.Repeat:
|
||||
_cache.IncreaseDepth( ( int )ExpCompileStateCode.RepeatLoop );
|
||||
return;
|
||||
case ExpKeyword.While:
|
||||
_cache.IncreaseDepth( ( int )ExpCompileStateCode.UntilLoop );
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="ExpSyntaxAnalyzer.ErrorProcess.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;
|
||||
|
||||
namespace StgSharp.Script.Express
|
||||
{
|
||||
public partial class ExpSyntaxAnalyzer
|
||||
{
|
||||
|
||||
public void ThrowCompileException( int errorCode )
|
||||
{
|
||||
switch( errorCode )
|
||||
{
|
||||
case 0 or 1:
|
||||
return;
|
||||
case TokenTypeNotMatch:
|
||||
throw new Exception();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="ExpSyntaxAnalyzer.If.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 System.Xml.Linq;
|
||||
|
||||
using ExpKeyword = StgSharp.Script.Express.ExpressCompile.Keyword;
|
||||
|
||||
namespace StgSharp.Script.Express
|
||||
{
|
||||
public partial class ExpSyntaxAnalyzer
|
||||
{
|
||||
|
||||
private bool AppendToken_IfBranch( Token t )
|
||||
{
|
||||
switch( t.Value )
|
||||
{
|
||||
case ExpKeyword.If:
|
||||
IfBranchStateCache state = new IfBranchStateCache();
|
||||
_cache.CurrentDepthMark.StateCache = state;
|
||||
state.CurrentState = t.Value;
|
||||
return true;
|
||||
case ExpKeyword.Then:
|
||||
state = _cache.StateOfCurrentDepth<IfBranchStateCache>();
|
||||
if( state.CurrentState == ExpKeyword.If )
|
||||
{
|
||||
while( _cache.TryPopOperator( out Token op ) ) {
|
||||
ConvertAndPushOneOperator( op );
|
||||
}
|
||||
_cache.PopOperand( out _, out ExpNode? node );
|
||||
state.CurrentState = t.Value;
|
||||
state.BoolExpression = node;
|
||||
} else
|
||||
{
|
||||
throw new ExpCompileException(
|
||||
t, $"Keyword {t.Value} should be after keyword {ExpKeyword.Then}" );
|
||||
}
|
||||
return true;
|
||||
case ExpKeyword.Else:
|
||||
state = _cache.StateOfCurrentDepth<IfBranchStateCache>();
|
||||
if( state.CurrentState == ExpKeyword.Then )
|
||||
{
|
||||
ExpNode node = _cache.PackAllStatements();
|
||||
state.CurrentState = t.Value;
|
||||
state.ExpressionIfTrue = node;
|
||||
} else
|
||||
{
|
||||
throw new ExpCompileException(
|
||||
t, $"Keyword {t.Value} should be after keyword {ExpKeyword.Then}" );
|
||||
}
|
||||
return true;
|
||||
|
||||
case ExpKeyword.EndIf:
|
||||
state = _cache.StateOfCurrentDepth<IfBranchStateCache>();
|
||||
if( state.CurrentState == ExpKeyword.Then )
|
||||
{
|
||||
ExpNode trueNode = _cache.PackAllStatements();
|
||||
state.CurrentState = t.Value;
|
||||
state.ExpressionIfTrue = trueNode;
|
||||
state.ExpressionIfFalse = ExpNode.Empty;
|
||||
} else if( state.CurrentState == ExpKeyword.Else )
|
||||
{
|
||||
ExpNode falseNode = _cache.PackAllStatements();
|
||||
state.CurrentState = t.Value;
|
||||
state.ExpressionIfFalse = falseNode;
|
||||
} else
|
||||
{
|
||||
throw new ExpCompileException(
|
||||
t,
|
||||
$"Keyword {t.Value} should be after keyword {ExpKeyword.Then} or {ExpKeyword.Else}" );
|
||||
}
|
||||
ExpIfNode ifNode = new ExpIfNode(
|
||||
state.Begin, state.BoolExpression, state.ExpressionIfTrue,
|
||||
state.ExpressionIfFalse );
|
||||
_cache.DecreaseDepth();
|
||||
_cache.StatementsInDepth.Push( ifNode );
|
||||
_cache.PushOperand( ifNode );
|
||||
return true;
|
||||
default:
|
||||
AppendToken_common( t );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class IfBranchStateCache : ICompileDepthState
|
||||
{
|
||||
|
||||
public ExpNode BoolExpression { get; set; }
|
||||
|
||||
public ExpNode ExpressionIfTrue { get; set; }
|
||||
|
||||
public ExpNode ExpressionIfFalse { get; set; }
|
||||
|
||||
public string CurrentState { get; set; }
|
||||
|
||||
public Token Begin { get; set; }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="ExpSyntaxAnalyzer.OperatorParser.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.ExpressCompile.Keyword;
|
||||
|
||||
namespace StgSharp.Script.Express
|
||||
{
|
||||
public partial class ExpSyntaxAnalyzer
|
||||
{
|
||||
|
||||
public int CompareOperatorPrecedence( Token left, Token right )
|
||||
{
|
||||
ExpressCompile.TryGetOperatorPrecedence( left.Value, out int leftPrecedence );
|
||||
ExpressCompile.TryGetOperatorPrecedence( right.Value, out int rightPrecedence );
|
||||
return leftPrecedence - rightPrecedence;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WARNING: This method cannot process INDEXOF, FUNCTION CALLING, LOOP and any ENDING
|
||||
/// SYMBOLS.
|
||||
/// </summary>
|
||||
private ExpNode ConvertAndPushOneOperator( 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 right = GetNextOperandCache();
|
||||
ExpNode left = GetNextOperandCache();
|
||||
switch( t.Value )
|
||||
{
|
||||
case ExpKeyword.Add:
|
||||
node = ExpBinaryOperatorNode.Add( t, left, right );
|
||||
return true;
|
||||
case ExpKeyword.Sub:
|
||||
node = ExpBinaryOperatorNode.Sub( t, left, right );
|
||||
return true;
|
||||
case ExpKeyword.Mul:
|
||||
node = ExpBinaryOperatorNode.Mul( t, left, right );
|
||||
return true;
|
||||
case ExpKeyword.Div:
|
||||
node = ExpBinaryOperatorNode.Div( t, left, right );
|
||||
return true;
|
||||
case ExpKeyword.Equal:
|
||||
node = ExpBinaryOperatorNode.EqualTo( t, left, right );
|
||||
return true;
|
||||
case ExpKeyword.NotEqual:
|
||||
node = ExpBinaryOperatorNode.NotEqualTo( t, left, right );
|
||||
return true;
|
||||
case ExpKeyword.GreaterThan:
|
||||
node = ExpBinaryOperatorNode.GreaterThan( t, left, right );
|
||||
return true;
|
||||
case ExpKeyword.LessThan:
|
||||
node = ExpBinaryOperatorNode.LessThan( t, left, right );
|
||||
return true;
|
||||
case ExpKeyword.Assignment:
|
||||
node = ExpBinaryOperatorNode.Assign( t, left, right );
|
||||
return true;
|
||||
default:
|
||||
node = ExpNode.Empty;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="ExpSyntaxAnalyzer.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.ExpressCompile.Keyword;
|
||||
|
||||
namespace StgSharp.Script.Express
|
||||
{
|
||||
public partial class ExpSyntaxAnalyzer
|
||||
{
|
||||
|
||||
private void ClosePrefixReverse( Token rightSeparator )
|
||||
{
|
||||
Token op;
|
||||
ExpNode root;
|
||||
if( _cache.OperatorAheadOfDepth == 0 )
|
||||
{
|
||||
if( _cache.OperandAheadOfDepth == 1 )
|
||||
{
|
||||
_cache.PopOperand( out _, out ExpNode? statement );
|
||||
_cache.StatementsInDepth.Push( statement );
|
||||
} else
|
||||
{
|
||||
ExpInvalidSyntaxException.ThrowNoOperator( rightSeparator );
|
||||
}
|
||||
} else
|
||||
{
|
||||
while( _cache.TryPopOperator( out op ) ) {
|
||||
ConvertAndPushOneOperator( op );
|
||||
}
|
||||
_cache.PopOperand( out _, out root );
|
||||
_cache.StatementsInDepth.Push( root );
|
||||
}
|
||||
|
||||
root = _cache.PackAllStatements();
|
||||
_cache.DecreaseDepth();
|
||||
if( IsSeparatorMatch( _cache.PeekOperator(), rightSeparator ) )
|
||||
{
|
||||
_cache.PopOperator();
|
||||
_cache.PushOperand( root );
|
||||
} else
|
||||
{
|
||||
throw new ExpCompileException(
|
||||
rightSeparator, "Ending of block does not match its begging" );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="ExpSyntaxAnalyzer.TokenSpliter.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 System.Xml.Schema;
|
||||
|
||||
using ExpKeyword = StgSharp.Script.Express.ExpressCompile.Keyword;
|
||||
|
||||
namespace StgSharp.Script.Express
|
||||
{
|
||||
public partial class ExpSyntaxAnalyzer
|
||||
{
|
||||
|
||||
private bool IsSeparatorMatch( Token leftSperator, Token rightSeparator )
|
||||
{
|
||||
return leftSperator.Value switch
|
||||
{
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
private bool TryAppendIndexLeft( Token t )
|
||||
{
|
||||
if( t.Flag != TokenFlag.Index_Left ) {
|
||||
return false;
|
||||
}
|
||||
if( _cache.TryPeekOperand( out bool isNode, out _, out ExpNode? node ) )
|
||||
{
|
||||
if( node.EqualityTypeConvert is not ExpCollectionBase ) {
|
||||
ExpInvalidSyntaxException.ThrowNonCollectionIndex( t );
|
||||
}
|
||||
}
|
||||
_cache.PushOperator( t );
|
||||
_cache.IncreaseDepth( ( int )ExpCompileStateCode.CollectionIndex );
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TryAppendIndexRight( Token t )
|
||||
{
|
||||
if( t.Flag != TokenFlag.Index_Right ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//reverse building
|
||||
ClosePrefixReverse( t );
|
||||
|
||||
//make index node
|
||||
_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;
|
||||
}
|
||||
|
||||
private bool TryAppendMember( Token t )
|
||||
{
|
||||
if( t.Flag != TokenFlag.Member ) {
|
||||
return false;
|
||||
}
|
||||
if( TryParseConstant( t ) ) {
|
||||
return true;
|
||||
}
|
||||
if( TryParseFunction( t ) ) {
|
||||
return true;
|
||||
}
|
||||
if( TryParseInstance( t ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//Many thing miss here
|
||||
|
||||
_cache.PushOperand( ExpElementMemberNameNode.Create( t ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TryAppendMiddleSeparator( Token t )
|
||||
{
|
||||
if( t.Flag != TokenFlag.Separator_Middle ) {
|
||||
return false;
|
||||
}
|
||||
while( _cache.OperatorAheadOfDepth > 0 )
|
||||
{
|
||||
_cache.TryPopOperator( out Token op );
|
||||
ExpNode node = ConvertAndPushOneOperator( op );
|
||||
}
|
||||
switch( _cache.OperandAheadOfDepth )
|
||||
{
|
||||
case 0:
|
||||
if( t.Value == ";" ) {
|
||||
return true;
|
||||
}
|
||||
_cache.StatementsInDepth.Push( ExpNode.Empty );
|
||||
goto case 1;
|
||||
case 1:
|
||||
_cache.PopOperand( out _, out ExpNode? statement );
|
||||
_cache.StatementsInDepth.Push( statement );
|
||||
return true;
|
||||
default:
|
||||
ExpInvalidSyntaxException.ThrowNoOperator( t );
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TryAppendNumAndStrLiteral( Token t )
|
||||
{
|
||||
if( ( t.Flag & ( TokenFlag.String | TokenFlag.Number ) ) == 0 ) {
|
||||
return false;
|
||||
}
|
||||
_cache.PushOperand( ExpElementInstance.CreateLiteral( t ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TryAppendPrefixSeparator( Token t )
|
||||
{
|
||||
if( t.Flag != TokenFlag.Separator_Left ) {
|
||||
return false;
|
||||
}
|
||||
_cache.PushOperator( t );
|
||||
_cache.IncreaseDepth( ( int )ExpCompileStateCode.Common );
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TryAppendPrefixSeparatorEnd( Token t )
|
||||
{
|
||||
if( t.Flag != TokenFlag.Separator_Right ) {
|
||||
return false;
|
||||
}
|
||||
ClosePrefixReverse( t );
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TryAppendSymbol( Token t )
|
||||
{
|
||||
if( ( t.Flag & ( TokenFlag.Symbol_Unary | TokenFlag.Symbol_Binary ) ) == 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int cmp = -1;
|
||||
processPrecedence:
|
||||
if( _cache.TryPeekOperator( out Token tmp ) )
|
||||
{
|
||||
cmp = CompareOperatorPrecedence( t, tmp );
|
||||
if( cmp >= 0 )
|
||||
{
|
||||
_cache.PopOperator();
|
||||
ExpNode node = ConvertAndPushOneOperator( tmp );
|
||||
goto processPrecedence;
|
||||
}
|
||||
}
|
||||
_cache.PushOperator( t );
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TryParseConstant( Token t )
|
||||
{
|
||||
switch( t.Value )
|
||||
{
|
||||
case ExpKeyword.E:
|
||||
_cache.PushOperand( new ExpRealNumberNode( t, MathF.E, true ) );
|
||||
return true;
|
||||
case ExpKeyword.Pi:
|
||||
_cache.PushOperand( new ExpRealNumberNode( t, MathF.PI, true ) );
|
||||
return true;
|
||||
default:
|
||||
if( ExpElementInstance.TryCreateLiteral( t, out ExpElementInstance? node ) )
|
||||
{
|
||||
_cache.PushOperand( node );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryParseFunction( Token t )
|
||||
{
|
||||
if( ExpKeyword.BuiltinFunctions.Contains( t.Value ) )
|
||||
{
|
||||
_cache.PushOperator( t );
|
||||
return true;
|
||||
} else if( _context.TryGetFunction( t.Value, out ExpFunctionSource? f ) )
|
||||
{
|
||||
_cache.PushOperand( t );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool TryParseInstance( Token t )
|
||||
{
|
||||
if( _local.TryGetMember( t.Value,
|
||||
out ExpNode? node ) && node is ExpElementInstance instance )
|
||||
{
|
||||
_cache.PushOperand( ExpInstanceReferenceNode.MakeReferenceFrom( t, instance ) );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="ExpSyntaxAnalyzer.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 Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
|
||||
using StgSharp.Threading;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Pipes;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ExpKeyword = StgSharp.Script.Express.ExpressCompile.Keyword;
|
||||
|
||||
namespace StgSharp.Script.Express
|
||||
{
|
||||
public partial class ExpSyntaxAnalyzer
|
||||
{
|
||||
|
||||
private const int EndLine = 1;
|
||||
private const int TokenGenerated = 0;
|
||||
private const int TokenTypeNotMatch = -1;
|
||||
|
||||
private CompileStack<ExpNode, IExpElementSource> _cache;
|
||||
private ExpNode _lastStatement;
|
||||
|
||||
private ExpSchema _context;
|
||||
private IExpElementSource _local;
|
||||
|
||||
public ExpSyntaxAnalyzer()
|
||||
{
|
||||
_cache = new CompileStack<ExpNode, IExpElementSource>();
|
||||
}
|
||||
|
||||
public ExpSyntaxAnalyzer( ExpSchema context, IExpElementSource local )
|
||||
{
|
||||
_cache = new CompileStack<ExpNode, IExpElementSource>();
|
||||
ArgumentNullException.ThrowIfNull( context );
|
||||
if( context is not ExpSchema_Builtin )
|
||||
{
|
||||
_context = context;
|
||||
} else
|
||||
{
|
||||
throw new InvalidCastException( "Not a valid Schema type" );
|
||||
}
|
||||
_local = local;
|
||||
}
|
||||
|
||||
/**/
|
||||
public void AppendToken( Token expToken )
|
||||
{
|
||||
switch( ( ExpCompileStateCode )TryEnterBranch( expToken ).Usage )
|
||||
{
|
||||
case ExpCompileStateCode.IfBranch:
|
||||
AppendToken_IfBranch( expToken );
|
||||
break;
|
||||
default:
|
||||
AppendToken_common( expToken );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Append a token to top of cache. This method will automatically convert token to node
|
||||
/// if meets separators or operators.
|
||||
/// </summary>
|
||||
public void AppendToken_common( Token expToken )
|
||||
{
|
||||
switch( expToken.Flag )
|
||||
{
|
||||
case TokenFlag.Symbol_Unary or TokenFlag.Symbol_Binary:
|
||||
TryAppendSymbol( expToken );
|
||||
break;
|
||||
case TokenFlag.Member:
|
||||
TryAppendMember( expToken );
|
||||
break;
|
||||
case TokenFlag.Separator_Left:
|
||||
TryAppendPrefixSeparator( expToken );
|
||||
break;
|
||||
case TokenFlag.Separator_Right:
|
||||
TryAppendPrefixSeparatorEnd( expToken );
|
||||
break;
|
||||
case TokenFlag.Separator_Middle:
|
||||
TryAppendMiddleSeparator( expToken );
|
||||
break;
|
||||
case TokenFlag.Index_Left:
|
||||
TryAppendIndexLeft( expToken );
|
||||
break;
|
||||
case TokenFlag.Index_Right:
|
||||
TryAppendIndexRight( expToken );
|
||||
break;
|
||||
case TokenFlag.Number or TokenFlag.String:
|
||||
ExpElementInstance node = ExpElementInstance.CreateLiteral( expToken );
|
||||
_cache.PushOperand( node );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public ExpNode GetNextOperandCache()
|
||||
{
|
||||
if( _cache.PopOperand( out Token t, out ExpNode? n ) )
|
||||
{
|
||||
return n;
|
||||
} else
|
||||
{
|
||||
// process some rare case here
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private CompileDepthMark TryEnterBranch( Token t )
|
||||
{
|
||||
if( t.Flag == TokenFlag.String ) {
|
||||
return _cache.CurrentDepthMark;
|
||||
}
|
||||
switch( t.Value )
|
||||
{
|
||||
case ExpKeyword.Case:
|
||||
return _cache.IncreaseDepth( ( int )ExpCompileStateCode.CaseBranch );
|
||||
case ExpKeyword.If:
|
||||
return _cache.IncreaseDepth( ( int )ExpCompileStateCode.IfBranch );
|
||||
case ExpKeyword.Repeat:
|
||||
return _cache.IncreaseDepth( ( int )ExpCompileStateCode.RepeatLoop );
|
||||
default:
|
||||
return _cache.CurrentDepthMark;
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
public enum ExpCompileStateCode
|
||||
{
|
||||
|
||||
Common,
|
||||
ForLoop,
|
||||
RepeatLoop,
|
||||
UntilLoop,
|
||||
IfBranch,
|
||||
CaseBranch,
|
||||
CollectionIndex,
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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+469cb884729b9a2d0845a1e971d353c43ba6f5f9")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+36b6ad5a526ca6ef66d826f614e8476a99fe52f7")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("StgSharp.Script")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("StgSharp.Script")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"documents":{"D:\\NitloadIndustry\\研究项目\\1-Flagship\\TH2020\\ProjectFile\\内核源代码\\*":"https://raw.githubusercontent.com/Nitload-NSI/CCD_Github/ffd5825a051f04f4105ac5ed02e754176ce6f608/*"}}
|
||||
{"documents":{"D:\\NitloadIndustry\\研究项目\\1-Flagship\\TH2020\\ProjectFile\\内核源代码\\*":"https://raw.githubusercontent.com/Nitload-NSI/CCD_Github/36b6ad5a526ca6ef66d826f614e8476a99fe52f7/*"}}
|
||||
@@ -54,6 +54,8 @@ namespace StgSharp
|
||||
"c", new ExpIntNode( new Token( "c", 0, 0, TokenFlag.Number ), 1, false ) );
|
||||
LocalVariables.Add(
|
||||
"d", new ExpIntNode( new Token( "d", 0, 0, TokenFlag.Number ), 1, false ) );
|
||||
LocalVariables.Add(
|
||||
"e", new ExpIntNode( new Token( "e", 0, 0, TokenFlag.Number ), 1, false ) );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -119,21 +121,33 @@ namespace StgSharp
|
||||
internal static partial class Program
|
||||
{
|
||||
|
||||
private const string code = """
|
||||
a := ( b * E + d * 2 ) * d;
|
||||
(**)
|
||||
a := b + (c + d) - a;
|
||||
IF a = b THEN
|
||||
a := a * e;
|
||||
ELSE
|
||||
a := c * e;
|
||||
END_IF
|
||||
(**)
|
||||
""";
|
||||
|
||||
public static void ExpLinearExpressionTest()
|
||||
{
|
||||
ExpressCompile.InitCompile();
|
||||
ScriptSourceTransmitter transmitter = new ScriptSourceTransmitter( "END", 0 );
|
||||
|
||||
//Console.WriteLine( @$"a := ( b * E + d * 2 ) * d;" );
|
||||
transmitter.WriteLine( @$"a := ( b * E + d * 2 ) * d;" );
|
||||
|
||||
transmitter.WriteLine( @"a := b + (c + d) * a;" );
|
||||
foreach( string line in code.Split(
|
||||
Environment.NewLine, StringSplitOptions.RemoveEmptyEntries ) ) {
|
||||
transmitter.WriteLine( line );
|
||||
}
|
||||
transmitter.EndWriting();
|
||||
ExpSourceReader reader = new ExpSourceReader( transmitter );
|
||||
/**/
|
||||
ExpTestFuncSource func = new ExpTestFuncSource( "test", transmitter );
|
||||
TestSchema testSchema = new TestSchema( func );
|
||||
ExpNodeGenerator generator = new ExpNodeGenerator( testSchema, func );
|
||||
ExpSyntaxAnalyzer generator = new ExpSyntaxAnalyzer( testSchema, func );
|
||||
/**/
|
||||
|
||||
while( reader.TryReadToken( out Token t ) )
|
||||
|
||||
@@ -14,7 +14,7 @@ using System.Reflection;
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("StgSharpDebug")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+ffd5825a051f04f4105ac5ed02e754176ce6f608")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+36b6ad5a526ca6ef66d826f614e8476a99fe52f7")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("StgSharpDebug")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("StgSharpDebug")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"documents":{"D:\\NitloadIndustry\\研究项目\\1-Flagship\\TH2020\\ProjectFile\\内核源代码\\*":"https://raw.githubusercontent.com/Nitload-NSI/CCD_Github/ffd5825a051f04f4105ac5ed02e754176ce6f608/*"}}
|
||||
{"documents":{"D:\\NitloadIndustry\\研究项目\\1-Flagship\\TH2020\\ProjectFile\\内核源代码\\*":"https://raw.githubusercontent.com/Nitload-NSI/CCD_Github/36b6ad5a526ca6ef66d826f614e8476a99fe52f7/*"}}
|
||||
Reference in New Issue
Block a user