//----------------------------------------------------------------------- //----------------------------------------------------------------------- // file="ExpSourceReader.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 CommunityToolkit.HighPerformance; using StgSharp.Intrinsic; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; namespace StgSharp.Script.Express { public partial class ExpSourceReader { private const int SingleComment = 0x2D2D, // -- MultiLineBegin = 0x282A, // (* MultiLineEnd = 0x2A29; // *) private Regex _nextWordTokenPattern = GetNextWordTokenPattern(), _; private bool _isReadingMultiLineComment; private int _index; private IScriptSourceProvider _provider; private string _lineCache; public ExpSourceReader( IScriptSourceProvider provider ) { _provider = provider; } [GeneratedRegex(@"(?[a-zA-Z][a-zA-Z0-9_]*)(?\s|\W)(?.*)")] internal static partial Regex GetNextWordTokenPattern(); /// /// 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. (*Just /// Like The Comment Here*) Will Not Be Removed /// /// public unsafe ReadOnlySpan ReadLine() { while( string.IsNullOrEmpty( _lineCache ) || _index >= _lineCache.Length || _isReadingMultiLineComment ) { _lineCache = _provider.ReadLine(); if( _isReadingMultiLineComment ) { int index; fixed( char* cPtr = _lineCache.AsSpan() ) { index = UnsafeCompute.IndexOfCharPair( cPtr, MultiLineEnd, _lineCache.Length ); } if( index != -1 ) { _lineCache = string.Empty; continue; } } } return _lineCache.AsSpan().Slice( _index ); } public unsafe ReadOnlySpan ReadToken( out string operand ) { int tokenBegin,tokenEnd,mark; readLine: } /* public string ReadNoCommentLine() { string line = string.Empty; while( TryReadNoCommentLine( ref line ) ) { } return line; } //Returns true when no usable string returns private bool TryReadNoCommentLine( ref string line ) { int _index; string str = _provider.ReadLine(); if( string.IsNullOrEmpty( str ) ) { return true; } if( _isReadingMultiLineComment ) { _index = str.LastIndexOf( @"*)" ) + 2; //calc by beginning of code if( _index == 1 || _index >= str.Length ) { return true; } line = str.SliceAndTrim( _index ); _isReadingMultiLineComment = false; return string.IsNullOrEmpty(line); } _index = str.IndexOf( @"--" ); if( _index != -1 ) { line = str.SliceAndTrim( 0, _index ); return string.IsNullOrEmpty(str); } _index = str.IndexOf(@"(*"); if (_index > 0) { if (TrySliceMultiLineCommentInSingleLine(ref str, _index)) { line = str; return string.IsNullOrEmpty(str); } line = str.SliceAndTrim(0,_index); _isReadingMultiLineComment = true; return string.IsNullOrEmpty(str); } line = str; return string.IsNullOrEmpty(str); } //returns true when a usable string returns private unsafe bool TrySliceMultiLineCommentInSingleLine(ref string source, int commentBegin) { string origin = source; int _index = origin.IndexOf("*)",commentBegin); if (_index == -1) { return false; } _index += 2; int begin = commentBegin - 1; ReadOnlySpan sourceSpan = origin.AsSpan(); while (begin >= 0 && char.IsWhiteSpace(sourceSpan[begin])) { begin--; } while (_index < origin.Length && char.IsWhiteSpace(sourceSpan[_index])) { _index++; } if (begin == 0 && _index == origin.Length - 1) { source = string.Empty; return true; } fixed (char* cPtr = sourceSpan) { int secLength = origin.Length - _index; Span o = new Span(cPtr, origin.Length); Span s = o.Slice(0, begin + 1 + secLength); Span sec = o.Slice(_index), dest = o.Slice(begin+1, secLength); sec.CopyTo(dest); source = new string(s); } return true; } /**/ } }