diff --git a/StgSharp.Model/STEP/Analyser/ExpSyntaxAnalyzer.Common.cs b/StgSharp.Model/STEP/Analyser/ExpSyntaxAnalyzer.Common.cs new file mode 100644 index 00000000..c80d9d27 --- /dev/null +++ b/StgSharp.Model/STEP/Analyser/ExpSyntaxAnalyzer.Common.cs @@ -0,0 +1,281 @@ +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +// file="ExpSyntaxAnalyzer.Common.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.Script; +using StgSharp.Script.Express; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Xml.Schema; + +using ExpKeyword = StgSharp.Script.Express.ExpressCompile.Keyword; + +namespace StgSharp.Modeling.Step +{ + internal partial class StepExpSyntaxAnalyzer + { + + private static Regex _entityTypeCheckPattern = GetEntityTypeCheckPattern(); + + [GeneratedRegex( @"^[A-Z_]+$", RegexOptions.Singleline )] + private static partial Regex GetEntityTypeCheckPattern(); + + private bool IsSeparatorMatch( Token leftSeparator, Token rightSeparator ) + { + return leftSeparator.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 ExpSyntaxNode? 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 ExpSyntaxNode? expNode ); + if( !_cache.PopOperand( out Token colleToken, out ExpSyntaxNode? 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; + } + if( TryParseKeyword( t ) ) { + return true; + } + if( TryParseElementName( 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 ); + ExpSyntaxNode node = ConvertAndPushOneOperator( op ); + } + switch( _cache.OperandAheadOfDepth ) + { + case 0: + if( t.Value == ";" ) { + return true; + } + _cache.StatementsInDepth.Push( ExpSyntaxNode.Empty ); + goto case 1; + case 1: + _cache.PopOperand( out _, out ExpSyntaxNode? statement ); + _cache.StatementsInDepth.Push( statement ); + if( t.Value == ";" ) { + StepEntityInitStatements.Enqueue( 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(); + ExpSyntaxNode 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 TryParseElementName( Token t ) + { + if( _context.TryGetType( t.Value, out ExpTypeSource? type ) ) + { + _cache.PushOperand( ExpMetaRefNode.RefType( t, type ) ); + return true; + } + if( _context.TryGetEntity( t.Value, out ExpEntitySource? entity ) ) + { + _cache.PushOperand( ExpMetaRefNode.RefEntity( t, entity ) ); + return true; + } + return false; + } + + private bool TryParseFunction( Token t ) + { + if( _entityTypeCheckPattern.IsMatch( t.Value ) ) { + _cache.PushOperator( t ); + } + return false; + } + + private bool TryParseInstance( Token t ) + { + if( t.Value[ 0 ] == '#' ) + { + _cache.PushOperand( StepEntityInstanceNode.Register( t ) ); + return true; + } + return false; + } + + private bool TryParseKeyword( Token t ) + { + switch( t.Value ) + { + case ExpKeyword.Return: + _cache.PushOperator( t ); + return true; + case ExpKeyword.Skip: + _cache.PushOperand( ExpProcedureControlNode.Skip( t ) ); + return true; + default: + return false; + } + } + + } +} diff --git a/StgSharp.Model/STEP/Analyser/ExpSyntaxAnalyzer.ErrorProcess.cs b/StgSharp.Model/STEP/Analyser/ExpSyntaxAnalyzer.ErrorProcess.cs new file mode 100644 index 00000000..d4eda496 --- /dev/null +++ b/StgSharp.Model/STEP/Analyser/ExpSyntaxAnalyzer.ErrorProcess.cs @@ -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.Modeling.Step +{ + internal partial class StepExpSyntaxAnalyzer + { + + public void ThrowCompileException( int errorCode ) + { + switch( errorCode ) + { + case 0 or 1: + return; + case TokenTypeNotMatch: + throw new Exception(); + default: + break; + } + } + + } +} diff --git a/StgSharp.Model/STEP/Analyser/ExpSyntaxAnalyzer.OperatorParser.cs b/StgSharp.Model/STEP/Analyser/ExpSyntaxAnalyzer.OperatorParser.cs new file mode 100644 index 00000000..54e553c0 --- /dev/null +++ b/StgSharp.Model/STEP/Analyser/ExpSyntaxAnalyzer.OperatorParser.cs @@ -0,0 +1,148 @@ +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +// 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 StgSharp.Model.Step.SyntaxNode; +using StgSharp.Script; +using StgSharp.Script.Express; + +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.Modeling.Step +{ + internal partial class StepExpSyntaxAnalyzer + { + + 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 ExpSyntaxNode node ) + { + ExpSyntaxNode 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 = ExpSyntaxNode.Empty; + return false; + } + } + + /// + /// WARNING: This method cannot process INDEXOF, FUNCTION CALLING, LOOP and any ENDING + /// SYMBOLS. + /// + private ExpSyntaxNode ConvertAndPushOneOperator( Token op ) + { + switch( op.Flag ) + { + case TokenFlag.Symbol_Unary: + TryGenerateUnaryNode( op, out ExpSyntaxNode? node ); + _cache.PushOperand( node ); + return node; + case TokenFlag.Symbol_Binary: + TryGenerateBinaryNode( op, out node ); + _cache.PushOperand( node ); + return node; + case TokenFlag.Member: + _cache.PopOperand( out _, out ExpSyntaxNode? p ); + StepEntityInitCaller caller = StepEntityInitCaller.CreateCaller( op.Value ); + node = ExpFunctionCallingNode.CallFunction( op, caller, p ); + _cache.PushOperand( node ); + return node; + default: + throw new NotImplementedException(); + } + } + + private bool TryGenerateBinaryNode( Token t, out ExpSyntaxNode node ) + { + ExpSyntaxNode right = GetNextOperandCache(); + ExpSyntaxNode 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; + case ExpKeyword.InstanceEqual: + node = ExpBinaryOperatorNode.CompareInstanceEqual( t, left, right ); + return true; + case ExpKeyword.InstanceNotEqual: + node = ExpBinaryOperatorNode.CompareInstanceNotEqual( t, left, right ); + return true; + default: + node = ExpSyntaxNode.Empty; + return false; + } + } + + } +} diff --git a/StgSharp.Model/STEP/Analyser/ExpSyntaxAnalyzer.PrefixReverseAnalysing.cs b/StgSharp.Model/STEP/Analyser/ExpSyntaxAnalyzer.PrefixReverseAnalysing.cs new file mode 100644 index 00000000..5312634d --- /dev/null +++ b/StgSharp.Model/STEP/Analyser/ExpSyntaxAnalyzer.PrefixReverseAnalysing.cs @@ -0,0 +1,85 @@ +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +// 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 StgSharp.Script; +using StgSharp.Script.Express; + +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.Modeling.Step +{ + internal partial class StepExpSyntaxAnalyzer + { + + private void ClosePrefixReverse( Token rightSeparator ) + { + Token op; + ExpSyntaxNode root; + if( _cache.OperatorAheadOfDepth == 0 ) + { + if( _cache.OperandAheadOfDepth == 1 ) + { + _cache.PopOperand( out _, out ExpSyntaxNode? 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" ); + } + } + + } +} diff --git a/StgSharp.Model/STEP/Analyser/ExpSyntaxAnalyzer.cs b/StgSharp.Model/STEP/Analyser/ExpSyntaxAnalyzer.cs new file mode 100644 index 00000000..88406407 --- /dev/null +++ b/StgSharp.Model/STEP/Analyser/ExpSyntaxAnalyzer.cs @@ -0,0 +1,149 @@ +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +// 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.Script; +using StgSharp.Script.Express; +using StgSharp.Threading; + +using System; +using System.Collections.Concurrent; +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.Modeling.Step +{ + internal partial class StepExpSyntaxAnalyzer : ISyntaxAnalyzer + { + + private const int EndLine = 1; + private const int TokenGenerated = 0; + private const int TokenTypeNotMatch = -1; + + private CompileStack _cache; + private ExpSchema _context; + private ExpSyntaxNode _lastStatement; + private IExpElementSource _local; + + public StepExpSyntaxAnalyzer() + { + _cache = new CompileStack(); + } + + public StepExpSyntaxAnalyzer( ExpSchema context, IExpElementSource local ) + { + _cache = new CompileStack(); + ArgumentNullException.ThrowIfNull( context ); + if( context is not ExpSchema_Builtin ) + { + _context = context; + } else + { + throw new InvalidCastException( "Not a valid Schema type" ); + } + _local = local; + } + + public ConcurrentQueue StepEntityInitStatements { get; } = new ConcurrentQueue( + ); + + /// + /// Append a token to top of cache. This method will automatically convert token to node + /// if meets separators or operators. + /// + public void AppendToken( Token expToken ) + { + switch( expToken.Flag ) + { + case TokenFlag.Symbol_Unary or TokenFlag.Symbol_Binary: + TryAppendSymbol( expToken ); + break; + case TokenFlag.Number or TokenFlag.String: + ExpElementInstance node = ExpElementInstance.CreateLiteral( expToken ); + _cache.PushOperand( node ); + 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.Member: + TryAppendMember( expToken ); + break; + default: + break; + } + } + + public ExpSyntaxNode GetNextOperandCache() + { + if( _cache.PopOperand( out Token t, out ExpSyntaxNode? n ) ) + { + return n; + } else + { + // process some rare case here + } + + throw new NotImplementedException(); + } + + public enum ExpCompileStateCode + { + + Common, + ForLoop, + RepeatLoop, + UntilLoop, + IfBranch, + CaseBranch, + CollectionIndex, + + } + + } +} diff --git a/StgSharp.Model/STEP/Analyser/StepDataSectionsTranmitter.cs b/StgSharp.Model/STEP/Analyser/StepDataSectionsTranmitter.cs new file mode 100644 index 00000000..8a968c99 --- /dev/null +++ b/StgSharp.Model/STEP/Analyser/StepDataSectionsTranmitter.cs @@ -0,0 +1,104 @@ +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +// file="StepDataSectionsTranmitter.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 StgSharp.Script; + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StgSharp.Modeling.Step +{ + public class StepDataSectionTransmitter : IScriptSourceProvider + { + + private const string EndDataText = "ENDSEC;"; + + private bool _isEmpty; + private ConcurrentQueue _cache = new ConcurrentQueue(); + private int _line = 0; + + public bool IsEmpty => _isEmpty; + + public bool IsWriting { get; private set; } = true; + + public int Location => _line; + + public void EndWriting() + { + _cache.Enqueue( EndDataText ); + IsWriting = false; + } + + public string ReadLine() + { + _cache.TryDequeue( out string? line ); + while( !IsEmpty ) + { + if( _cache.TryDequeue( out line ) ) + { + if( line == EndDataText ) + { + _isEmpty = true; + return string.Empty; + } + _line++; + return line; + } + } + return string.Empty; + } + + public string ReadLine( out int position ) + { + string ret = ReadLine(); + position = _line; + return ret; + } + + public void WriteLine( string line ) + { + if( line == EndDataText ) { + EndWriting(); + } + _cache.Enqueue( line ); + } + + IScriptSourceProvider IScriptSourceProvider.Slice( int location, int count ) + { + throw new NotSupportedException(); + } + + } +} diff --git a/StgSharp.Model/STEP/Analyser/StepDataTokenReader.cs b/StgSharp.Model/STEP/Analyser/StepDataTokenReader.cs new file mode 100644 index 00000000..0ee131ce --- /dev/null +++ b/StgSharp.Model/STEP/Analyser/StepDataTokenReader.cs @@ -0,0 +1,117 @@ +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +// file="StepDataTokenReader.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 StgSharp.Modeling.Step; +using StgSharp.Script; +using StgSharp.Script.Express; + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; + +namespace StgSharp.Modeling.Step +{ + public class StepDataTokenReader : IScriptTokenReader + { + + private ExpTokenReader _reader; + + private HashSet token1Hash = [ + "T","F","UNSPECIFIED" + ]; + private Queue _cache = new Queue(); + private StepDataSectionTransmitter _transmitter; + + public StepDataTokenReader( StepDataSectionTransmitter transmitter ) + { + _reader = new ExpTokenReader( transmitter ); + _reader.TokenReaderPreProcessor = new TokenPreReader(); + _transmitter = transmitter; + } + + public bool IsEmpty + { + get => _reader.IsEmpty && _transmitter.IsWriting; + } + + public Token ReadToken() + { + return _reader.ReadToken(); + } + + public bool TryReadToken( out Token t ) + { + return _reader.TryReadToken( out t ); + } + + private class TokenPreReader : ExpTokenReaderPreProcessor + { + + private static Regex NextEnumPattern = GetNextEnumPattern(); + + public override bool Process( string codeLine, int line, ref int current, out Token t ) + { + ReadOnlySpan chars = codeLine.AsSpan( current ); + char c = chars[ 0 ]; + if( c != '.' ) + { + t = Token.Empty; + return false; + } + Match match = NextEnumPattern.Match( codeLine, current ); + if( match.Success ) + { + int begin = match.Groups[ "begin" ].Index; + int end = match.Groups[ "end" ].Length; + int rest = match.Groups[ "rets" ].Length; + current = rest; + t = new Token( match.Groups[ "begin" ].Value, line, begin, TokenFlag.Enum ); + return true; + } else + { + t = Token.Empty; + return false; + } + } + + [GeneratedRegex( + @"(?\.[A-Za-z_]+\.)(?\s*)(?\S*)", + RegexOptions.Singleline )] + private static extern Regex GetNextEnumPattern(); + + } + + } +} diff --git a/StgSharp.Model/STEP/ExpressStepUtil.cs b/StgSharp.Model/STEP/ExpressStepUtil.cs new file mode 100644 index 00000000..4b15719c --- /dev/null +++ b/StgSharp.Model/STEP/ExpressStepUtil.cs @@ -0,0 +1,142 @@ +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +// file="ExpressStepUtil.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 StgSharp.Modeling.Step; +using StgSharp.Script; +using StgSharp.Script.Express; + +using System; +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace StgSharp.Modeling.Step +{ + public class ExpressStepUtil : ExpSchema + { + + public const string AdvancedFaceText = "ADVANCED_FACE"; + public const string Axis2Placement2DText = "AXIS2_PLACEMENT_2D"; + public const string Axis2Placement3DText = "AXIS2_PLACEMENT_3D"; + public const string BSplineCurveWithKnotsText = "B_SPLINE_CURVE_WITH_KNOTS"; + public const string CartesianPointText = "CARTESIAN_POINT"; + public const string CircleText = "CIRCLE"; + public const string CylindricalSurfaceText = "CYLINDRICAL_SURFACE"; + public const string DirectionText = "DIRECTION"; + public const string EdgeCurveText = "EDGE_CURVE"; + public const string EdgeLoopText = "EDGE_LOOP"; + public const string EllipseText = "ELLIPSE"; + public const string FaceBoundText = "FACE_BOUND"; + public const string FaceOuterBoundText = "FACE_OUTER_BOUND"; + public const string LineText = "LINE"; + public const string OrientedEdgeText = "ORIENTED_EDGE"; + public const string PlaneText = "PLANE"; + public const string VectorText = "VECTOR"; + public const string VertexPointText = "VERTEX_POINT"; + + private static + HashSet names = [ + AdvancedFaceText, + Axis2Placement2DText, + Axis2Placement3DText, + BSplineCurveWithKnotsText, + CartesianPointText, + CircleText, + CylindricalSurfaceText, + DirectionText, + EdgeCurveText, + EdgeLoopText, + EllipseText, + FaceBoundText, + FaceOuterBoundText, + LineText, + OrientedEdgeText, + PlaneText, + VectorText, + VertexPointText, + ]; + + private FrozenDictionary entitiesDefine; + + public ExpressStepUtil() + { + Dictionary tIndex = new Dictionary(); + } + + internal StepModel Current { get; set; } + + public override void LoadFromSource( ExpSchemaSource source ) + { + return; + } + + public override bool TryGetConst( string name, out ExpElementInstance c ) + { + c = null!; + return false; + } + + public override bool TryGetEntity( string name, out ExpEntitySource e ) + { + e = null!; + return false; + } + + public override bool TryGetFunction( string name, out ExpFunctionSource f ) + { + throw new NotImplementedException(); + } + + public override bool TryGetProcedure( string name, out ExpProcedureSource p ) + { + p = null!; + return false; + } + + public override bool TryGetRule( string name, out ExpRuleSource r ) + { + r = null!; + return false; + } + + public override bool TryGetSchemaInclude( string name, out ExpSchema include ) + { + include = null!; + return false; + } + + public override bool TryGetType( string name, out ExpTypeSource t ) + { + t = null!; + return false; + } + + } +} \ No newline at end of file diff --git a/StgSharp.Model/STEP/StepItemType.cs b/StgSharp.Model/STEP/StepItemType.cs new file mode 100644 index 00000000..e1431272 --- /dev/null +++ b/StgSharp.Model/STEP/StepItemType.cs @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +// file="StepItemType.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 StgSharp.Modeling.Step; +using StgSharp.Script; + +using System; + +namespace StgSharp.Modeling.Step +{ + public enum StepItemType + { + + Unknown, + AdvancedFace, + AxisPlacement2D, + AxisPlacement3D, + BSplineCurveWithKnots, + CartesianPoint, + Circle, + CylindricalSurface, + Direction, + EdgeCurve, + EdgeLoop, + Ellipse, + FaceBound, + FaceOuterBound, + Line, + OrientedEdge, + Plane, + Vector, + VertexPoint + + } +} + diff --git a/StgSharp.Model/STEP/StepReader.DataSectionReader.cs b/StgSharp.Model/STEP/StepReader.DataSectionReader.cs new file mode 100644 index 00000000..ea5a4ba1 --- /dev/null +++ b/StgSharp.Model/STEP/StepReader.DataSectionReader.cs @@ -0,0 +1,75 @@ +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +// file="StepDataReader.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 StgSharp.Modeling.Step; +using StgSharp.Modeling.Step; +using StgSharp.Script; + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.IO.MemoryMappedFiles; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; + +namespace StgSharp.Modeling.Step +{ + public partial class StepReader + { + + public StepDataSectionTransmitter DataTransmitter { get; } = new StepDataSectionTransmitter( + ); + + public async void ReadDataSection() + { + using( MemoryMappedViewStream ms = _memoryFile.CreateViewStream( + 0, _size, MemoryMappedFileAccess.Read ) ) + { + StreamReader sr = new StreamReader( ms ); + long pos = _headStart; + string line; + while( string.IsNullOrEmpty( line = sr.ReadLine()! ) ) { + DataTransmitter.WriteLine( line ); + } + sr.Dispose(); + } + } + + [GeneratedRegex( + @"^#(?[0-9]+)\s*?=\s*?(?\S.*?)\s*;$", + RegexOptions.Compiled | RegexOptions.Singleline )] + private static partial Regex GetExpressionSplitter(); + + } +} diff --git a/StgSharp.Model/STEP/StepReader.HeadReader.cs b/StgSharp.Model/STEP/StepReader.HeadReader.cs new file mode 100644 index 00000000..5892aca7 --- /dev/null +++ b/StgSharp.Model/STEP/StepReader.HeadReader.cs @@ -0,0 +1,111 @@ +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +// file="StepHeadReader.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.IO; +using System.IO.MemoryMappedFiles; +using System.Runtime.Serialization; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace StgSharp.Modeling.Step +{ + public partial class StepReader + { + + private static Regex expressionSplitter = new Regex( + @"^(?[A-Z_]+)\s?\((?.+)\)\;", RegexOptions.Compiled ); + /**/ + private StepInfo _info; + + public StepInfo GetInfo() + { + if( _info is not null ) { + return _info; + } + StepInfo info = new StepInfo(); + List constructorList = new List(); + using( MemoryMappedViewStream ms = _memoryFile.CreateViewStream( + 0, _size, MemoryMappedFileAccess.Read ) ) + { + using( StreamReader sr = new StreamReader( ms ) ) + { + long pos = _headStart; + ms.Seek( _headStart, SeekOrigin.Begin ); + while( pos <= _headEnd ) + { + string token = ReadToken( sr, ref pos ); + if( token == "HEADER;" ) + { + continue; + } + + if( token == "ENDSEC;" ) + { + break; + } + + GroupCollection match = expressionSplitter.Match( token ).Groups; + constructorList.Add( + new StepObjectConstructor( + 0, match[ "CALLER" ].ToString(), match[ "PARAM" ].ToString() ) ); + } + foreach( StepObjectConstructor constructor in constructorList ) + { + switch( constructor.Caller ) + { + case "FILE_DESCRIPTION": + info.Description = StepDataParser.ToString( constructor[ 0 ] ); + info.Level = StepDataParser.ToVersion( constructor[ 1 ] ); + break; + case "FILE_NAME": + info.Name = StepDataParser.ToString( constructor[ 0 ] ); + info.TimeStamp = StepDataParser.ToDateTime( constructor[ 1 ] ); + info.Author = StepDataParser.ToString( constructor[ 2 ] ); + info.Organization = StepDataParser.ToString( constructor[ 3 ] ); + info.PreprocessorVersion = StepDataParser.ToString( + constructor[ 4 ] ); + info.OriginatingSystem = StepDataParser.ToString( constructor[ 5 ] ); + info.Authorization = StepDataParser.ToString( constructor[ 6 ] ); + break; + default: + break; + } + } + } + } + return info; + } + /**/ + + } +} \ No newline at end of file diff --git a/StgSharp.Model/STEP/StepReader.ToModel.cs b/StgSharp.Model/STEP/StepReader.ToModel.cs new file mode 100644 index 00000000..fb4a9799 --- /dev/null +++ b/StgSharp.Model/STEP/StepReader.ToModel.cs @@ -0,0 +1,106 @@ +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +// file="StepReader.ToModel.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 StgSharp.Script; +using StgSharp.Script.Express; + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace StgSharp.Modeling.Step +{ + public partial class StepReader + { + + private volatile int _version = 0; + private StepDataTokenReader tokenReader; + + private StepExpSyntaxAnalyzer analyzer; + + private StepModel Model { get; set; } + + private Task ReadToModelTask { get; set; } + + public StepModel ReadToModel() + { + if( Model is not null ) { + return Model; + } + if( _version != 0 ) { + throw new InvalidOperationException( + "A ReadToModel method has been called and is running now, use Async version instead" ); + } + Interlocked.Increment( ref _version ); + GetInfo(); + tokenReader = new StepDataTokenReader( DataTransmitter ); + analyzer = new StepExpSyntaxAnalyzer(); + Task secTask = Task.Run( ReadDataSection ); + Task anTask = Task.Run( ReadStepToken ); + ConcurrentQueue initStatements = analyzer.StepEntityInitStatements; + Model = new StepModel( _info ); + while( initStatements.TryDequeue( out ExpSyntaxNode? statement ) || !anTask.IsCompleted ) + { + if( statement is null ) + { + Thread.Sleep( 0 ); + continue; + } + StepUninitializedEntity entity = StepUninitializedEntity.FromSyntax( + Model, statement ); + Model.AddUncertainEntity( entity.Id, entity ); + } + Task.WaitAll( secTask, anTask ); + return Model; + } + + public async Task ReadToModelAsync() + { + if( ReadToModelTask is null ) { + ReadToModelTask = Task.Run( ReadToModel ); + } + return await ReadToModelTask; + } + + private void ReadStepToken() + { + while( !tokenReader.IsEmpty ) + { + Token t = tokenReader.ReadToken(); + analyzer.AppendToken( t ); + } + } + + } +} diff --git a/StgSharp.Model/STEP/StepReader.cs b/StgSharp.Model/STEP/StepReader.cs new file mode 100644 index 00000000..0c2f685f --- /dev/null +++ b/StgSharp.Model/STEP/StepReader.cs @@ -0,0 +1,172 @@ +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +// file="StepReader.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 StgSharp; +using StgSharp.Script; +using StgSharp.Script.Express; + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.IO.MemoryMappedFiles; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; + +namespace StgSharp.Modeling.Step +{ + public partial class StepReader : IDisposable + { + + private const string fileLabel = "ISO-10303-21;"; + + private bool disposedValue; + private FileStream _fileStream; + private long _headStart = -1, _headEnd = -1, _dataStart = -1, _size; + private MemoryMappedFile _memoryFile; + + private StepReader() { } + + private StepReader( FileStream stream, long size ) + { + _fileStream = stream; + _size = size; + _memoryFile = MemoryMappedFile.CreateFromFile( + stream, mapName: null, size, MemoryMappedFileAccess.Read, HandleInheritability.None, + leaveOpen: true ); + } + + // ~StepReader() + // { + // Dispose(disposing: false); + // } + + public void Dispose() + { + Dispose( disposing: true ); + GC.SuppressFinalize( this ); + } + + public static bool FromFile( string path, out StepReader reader ) + { + FileInfo info = new FileInfo( path ); + if( !info.Exists ) + { + reader = null!; + return false; + } + FileStream stream = new FileStream( + path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, + useAsync: true ); + byte[] fileHead = new byte[40]; + stream.Read( fileHead, 0, fileLabel.Length ); + if( !Encoding.UTF8.GetString( fileHead ).Contains( fileLabel ) ) { + throw new InvalidDataException( "The given file is not a STEP file" ); + } + reader = new StepReader( stream, info.Length ); + reader.LocateSection(); + return reader != null; + } + + private void LocateSection() + { + long startPos = 0; + byte[] buffer = new byte[1024]; + Span bufferSpan = buffer, + headerSec = Encoding.UTF8.GetBytes( "HEADER;" ), + endsecSec = Encoding.UTF8.GetBytes( "ENDSEC;" ), + dataSec = Encoding.UTF8.GetBytes( "DATA;" ); + _fileStream.Position = 0; + for( ; startPos < _size; startPos += 1000 ) + { + _fileStream.Read( buffer ); + if( _headStart == -1 ) + { + long pos = bufferSpan.IndexOf( headerSec ); + if( pos >= 0 ) { + _headStart = startPos + pos; + } + } + if( _headEnd == -1 ) + { + long pos = bufferSpan.IndexOf( endsecSec ); + if( pos >= 0 ) { + _headEnd = startPos + pos; + } + } + if( _dataStart == -1 ) + { + long pos = bufferSpan.IndexOf( dataSec ); + if( pos >= 0 ) { + _dataStart = startPos + pos; + } + } else + { + break; + } + _fileStream.Seek( 1000, SeekOrigin.Current ); + } + } + + private string ReadToken( StreamReader reader, ref long posCache ) + { + StringBuilder token = new StringBuilder( 100 ); + while( token.Length == 0 || token[ token.Length - 1 ] != ';' ) + { + string subString = reader.ReadLine()!; + if( subString == null ) + { + break; + } + token.Append( subString.TrimStart() ); + } + posCache += token.Length; + return token.ToString(); + } + + private protected virtual void Dispose( bool disposing ) + { + if( !disposedValue ) + { + if( disposing ) + { + _fileStream.Dispose(); + _memoryFile.Dispose(); + } + + disposedValue = true; + } + } + + } +} diff --git a/StgSharp.Model/STEP/SyntaxNode/StepComplexEntityNode.cs b/StgSharp.Model/STEP/SyntaxNode/StepComplexEntityNode.cs new file mode 100644 index 00000000..d5cf4928 --- /dev/null +++ b/StgSharp.Model/STEP/SyntaxNode/StepComplexEntityNode.cs @@ -0,0 +1,67 @@ +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +// file="StepComplexEntityNode.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 StgSharp.Script.Express; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StgSharp.Model.Step +{ + public class StepComplexEntityNode : ExpSyntaxNode + { + + private ExpSyntaxNode _begin; + + public StepComplexEntityNode( ExpSyntaxNode node ) + : base( node.Source ) + { + _begin = node; + } + + public override ExpSyntaxNode Left => Empty; + + public override ExpSyntaxNode Right => _begin; + + public override IExpElementSource EqualityTypeConvert => throw new NotImplementedException(); + + public StepComplexEntityNode FromTuple( ExpSyntaxNode node ) + { + if( node is not ExpTupleNode tuple ) { + throw new ExpInvalidSyntaxException( "Node to convert is not a complex" ); + } + return new StepComplexEntityNode( tuple.Right ); + } + + } +} diff --git a/StgSharp.Model/STEP/SyntaxNode/StepEntityInitCaller.cs b/StgSharp.Model/STEP/SyntaxNode/StepEntityInitCaller.cs new file mode 100644 index 00000000..a96f430d --- /dev/null +++ b/StgSharp.Model/STEP/SyntaxNode/StepEntityInitCaller.cs @@ -0,0 +1,68 @@ +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +// file="StepEntityInitCaller.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.Modeling.Step; +using StgSharp.Script; +using StgSharp.Script.Express; + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StgSharp.Model.Step.SyntaxNode +{ + public class StepEntityInitCaller : ExpFunctionSource + { + + private static Dictionary _callers = new(); + + private StepEntityInitCaller( string name ) + : base( name, null ) + { + ReturningType = StepEntityType.Source; + } + + public static StepEntityInitCaller CreateCaller( string name ) + { + if( _callers.TryGetValue( name, out StepEntityInitCaller? caller ) ) { + return caller; + } + caller = new StepEntityInitCaller( name ); + _callers.Add( name, caller ); + return caller; + } + + } +} diff --git a/StgSharp.Model/obj/x64/Debug/net8.0/StgSharp.Model.AssemblyInfo.cs b/StgSharp.Model/obj/x64/Debug/net8.0/StgSharp.Model.AssemblyInfo.cs index 52577371..f8722827 100644 --- a/StgSharp.Model/obj/x64/Debug/net8.0/StgSharp.Model.AssemblyInfo.cs +++ b/StgSharp.Model/obj/x64/Debug/net8.0/StgSharp.Model.AssemblyInfo.cs @@ -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+b618fdf7b5295b190dcc6b7168e038d1d5a11455")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+a0f7476291d65b51de2055f8b2d69fa44348d04b")] [assembly: System.Reflection.AssemblyProductAttribute("StgSharp.Model")] [assembly: System.Reflection.AssemblyTitleAttribute("StgSharp.Model")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/StgSharp.Script/Common/IScriptTokenReader.cs b/StgSharp.Script/Common/IScriptTokenReader.cs index 43186003..88a3b380 100644 --- a/StgSharp.Script/Common/IScriptTokenReader.cs +++ b/StgSharp.Script/Common/IScriptTokenReader.cs @@ -33,6 +33,8 @@ namespace StgSharp.Script public interface IScriptTokenReader { + bool IsEmpty { get; } + Token ReadToken(); bool TryReadToken( out Token t ); diff --git a/StgSharp.Script/Express/Element/ExpFunction.cs b/StgSharp.Script/Express/Element/ExpFunction.cs index 5451e118..e2cc7961 100644 --- a/StgSharp.Script/Express/Element/ExpFunction.cs +++ b/StgSharp.Script/Express/Element/ExpFunction.cs @@ -54,6 +54,8 @@ namespace StgSharp.Script.Express public override ExpElementType ElementType => ExpElementType.Function; + public IExpElementSource ReturningType { get; protected set; } + public override IScriptSourceProvider SourceProvider => _transmitter; public override string Name => _name; diff --git a/StgSharp.Script/Express/ExpAstNode/ExpBinaryOperatorNode.cs b/StgSharp.Script/Express/ExpAstNode/ExpBinaryOperatorNode.cs index fdb39a41..a713a449 100644 --- a/StgSharp.Script/Express/ExpAstNode/ExpBinaryOperatorNode.cs +++ b/StgSharp.Script/Express/ExpAstNode/ExpBinaryOperatorNode.cs @@ -61,6 +61,8 @@ namespace StgSharp.Script.Express public override ExpSyntaxNode Right => _right; + public string Operator { get; private set; } + public static ExpBinaryOperatorNode Add( Token source, ExpSyntaxNode left, @@ -93,6 +95,7 @@ namespace StgSharp.Script.Express { _returnType = ExpInstantiableElement.Void, _nodeFlag = ExpNodeFlag.Operator_Binary | left._nodeFlag, + Operator = "=", CodeConvertTemplate = "{0} = {1}", }; } @@ -111,11 +114,11 @@ namespace StgSharp.Script.Express } public static ExpBinaryOperatorNode CompareInstanceNotEqual( - Token nsource, + Token source, ExpSyntaxNode left, ExpSyntaxNode right ) { - return new ExpBinaryOperatorNode( nsource, left, right ) + return new ExpBinaryOperatorNode( source, left, right ) { _returnType = ExpressCompile.ExpBool, _nodeFlag = ExpNodeFlag.BuiltinType_Boolean | ExpNodeFlag.Operator_Binary, @@ -128,13 +131,13 @@ namespace StgSharp.Script.Express ExpSyntaxNode left, ExpSyntaxNode right ) { - if( right is not ExpMetaRefNode metaref ) { + if( right is not ExpMetaRefNode metaRef ) { throw new ExpInvalidTypeException( "", right.EqualityTypeConvert.Name ); } return new ExpBinaryOperatorNode( source, left, right ) { - _returnType = metaref.SourceRef, + _returnType = metaRef.SourceRef, _nodeFlag = ExpNodeFlag.Operator_Binary, /* * 0. instance to convert diff --git a/StgSharp.Script/Express/ExpAstNode/ExpElementInitializingNode.cs b/StgSharp.Script/Express/ExpAstNode/ExpElementInitializingNode.cs index 475bdd31..de80c358 100644 --- a/StgSharp.Script/Express/ExpAstNode/ExpElementInitializingNode.cs +++ b/StgSharp.Script/Express/ExpAstNode/ExpElementInitializingNode.cs @@ -65,6 +65,9 @@ namespace StgSharp.Script.Express ExpMetaRefNode type, ExpSyntaxNode init ) { + if( init is ExpTupleNode tupleNode ) { + init = tupleNode.Right; + } ExpElementInitializingNode node = new ExpElementInitializingNode( source, type, init ); return node; } diff --git a/StgSharp.Script/Express/ExpAstNode/ExpFunctionCallingNode.cs b/StgSharp.Script/Express/ExpAstNode/ExpFunctionCallingNode.cs index d81fd1fc..16ebc340 100644 --- a/StgSharp.Script/Express/ExpAstNode/ExpFunctionCallingNode.cs +++ b/StgSharp.Script/Express/ExpAstNode/ExpFunctionCallingNode.cs @@ -58,8 +58,7 @@ namespace StgSharp.Script.Express public ExpFunctionSource FunctionCaller => _function; - public override ExpInstantiableElement EqualityTypeConvert => throw new NotImplementedException( - ); + public override ExpInstantiableElement EqualityTypeConvert => _function.; public override ExpSyntaxNode Left => Empty; @@ -75,6 +74,9 @@ namespace StgSharp.Script.Express ExpFunctionSource function, ExpSyntaxNode param ) { + if( param is ExpTupleNode ) { + param = param.Right; + } return new ExpFunctionCallingNode( source, function, param ); }