This commit is contained in:
Nitload
2025-08-25 09:50:30 +08:00
parent bd0e31e922
commit 1359ff4ecc
1630 changed files with 738486 additions and 2399 deletions
+61
View File
@@ -0,0 +1,61 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="AbstractSyntaxTree.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.Collections;
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Schema;
namespace StgSharp.Script
{
public sealed class AbstractSyntaxTree<TNode, TType>
where TNode: IASTNode<TNode, TType>
where TType: ITypeSource<TType>
{
private List<TNode> _allToken = new();
private TNode _root;
public int Count
{
get { return _allToken.Count; }
}
public TNode Root => _root;
public bool Contains( TNode node )
{
return _allToken.Contains( node );
}
}
}
+108
View File
@@ -0,0 +1,108 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="CodeLineHelper.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.Text;
namespace StgSharp.Script
{
public static class CodeLineHelper
{
public static string SliceAndTrim( this string line, int startIndex )
{
if( line == null ) {
throw new ArgumentNullException( nameof( line ) );
}
if( startIndex < 0 || startIndex >= line.Length ) {
throw new ArgumentOutOfRangeException( nameof( startIndex ) );
}
ReadOnlySpan<char> sourceSpan = line.AsSpan();
ReadOnlySpan<char> subSpan = sourceSpan.Slice( startIndex );
int start = 0;
while( start < subSpan.Length && char.IsWhiteSpace(
subSpan[ start ] ) ) {
start++;
}
int end = subSpan.Length - 1;
while( end >= start && char.IsWhiteSpace( subSpan[ end ] ) ) {
end--;
}
if( start > end ) {
return string.Empty;
}
int finalLength = end - start + 1;
return new string( subSpan.Slice( start, finalLength ) );
}
public static string SliceAndTrim(
this string line,
int startIndex,
int length )
{
if( line == null ) {
throw new ArgumentNullException( nameof( line ) );
}
if( startIndex < 0 || startIndex >= line.Length ) {
throw new ArgumentOutOfRangeException( nameof( startIndex ) );
}
if( length < 0 || startIndex + length > line.Length ) {
throw new ArgumentOutOfRangeException( nameof( length ) );
}
ReadOnlySpan<char> sourceSpan = line.AsSpan();
ReadOnlySpan<char> subSpan = sourceSpan.Slice( startIndex, length );
int start = 0;
while( start < subSpan.Length && char.IsWhiteSpace(
subSpan[ start ] ) ) {
start++;
}
int end = subSpan.Length - 1;
while( end >= start && char.IsWhiteSpace( subSpan[ end ] ) ) {
end--;
}
if( start > end ) {
return string.Empty;
}
int finalLength = end - start + 1;
return new string( subSpan.Slice( start, finalLength ) );
}
}
}
+69
View File
@@ -0,0 +1,69 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="IASTNode.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.Collections;
using StgSharp.Script.Express;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace StgSharp.Script
{
public interface IASTNode<TNode, TType> where TNode: IASTNode<TNode, TType>
where TType: ITypeSource<TType>
{
long NodeFlag { get; }
string CodeConvertTemplate { get; }
TNode Previous { get; set; }
TNode Next { get; set; }
TNode Left { get; }
TNode Right { get; }
static abstract TNode Empty { get; }
Token Source { get; }
TType EqualityTypeConvert { get; }
void AppendNode( TNode nextToken );
void PrependNode( TNode previusNode );
}
}
@@ -0,0 +1,51 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpBuiltinConstant.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;
namespace StgSharp.Script.Express
{
internal partial class ExpSchema_Nitload
{
public ExpTypeSource IntType
{
get;
private set;
}
public ExpTypeSource FloatType
{
get;
private set;
}
}
}
@@ -0,0 +1,45 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="IExpBuiltinType.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 interface IExpBuiltinType<TSelf> where TSelf: ExpElementInstance, IExpBuiltinType<TSelf>
{
static abstract ExpElementInstance CreateInstance();
}
}
@@ -0,0 +1,64 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpProcedure.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 class ExpProcedure : ExpImmutableElement
{
public override ExpElementType ElementType => ExpElementType.Procedure;
public override IScriptSourceProvider SourceProvider => throw new NotImplementedException();
public override string Name => throw new NotImplementedException();
public override void Analyse()
{
throw new NotImplementedException();
}
public override ExpNode MakeReference( params object[] options )
{
throw new NotImplementedException();
}
public override bool TryGetMember( string name, out ExpNode memberNode )
{
throw new NotImplementedException();
}
}
}
@@ -0,0 +1,128 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpTypeInstance.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.Generic;
namespace StgSharp.Script.Express
{
public class ExpTypeInstance : ExpElementInstanceBase
{
public ExpTypeInstance( string name, ExpSchema context )
: base( name, context ) { }
public override ExpBaseNode Left => throw new NotImplementedException();
public override ExpBaseNode Right => throw new NotImplementedException();
public override ExpInstantiableElementBase EqualityTypeConvert => throw new NotImplementedException(
);
public override string TypeName => throw new NotImplementedException();
}
public class ExpTypeSource : IExpElementSource
{
private ScriptSourceTransmitter _transmitter;
private string _name;
protected bool _isBuiltinType;
protected ExpTypeSource( string name )
{
_name = name;
_transmitter = ScriptSourceTransmitter.Empty;
_isBuiltinType = true;
}
public ExpTypeSource( string name, ScriptSourceTransmitter transmitter )
{
_name = name;
_transmitter = transmitter;
_isBuiltinType = false;
}
public bool IsLanguageBuiltinType
{
get => _isBuiltinType;
}
public ExpElementType ElementType => ExpElementType.Type;
public ExpTypeSource Void
{
get => ExpVoidType.Only;
}
public IScriptSourceProvider SourceProvider => _transmitter;
public string Name => _name;
public virtual void Analyse()
{
throw new NotImplementedException();
}
public bool IsConvertable( IExpElementSource targetType )
{
throw new NotImplementedException();
}
public static bool IsNullOrVoid( IExpElementSource type )
{
return type == null || type == ExpVoidType.Only;
}
private class ExpVoidType : ExpTypeSource
{
private static readonly ExpVoidType _onlyInstance = new ExpVoidType(
);
private ExpVoidType() : base( string.Empty ) { }
public static ExpVoidType Only
{
get => _onlyInstance;
}
public override void Analyse()
{
return;
}
}
}
}
@@ -0,0 +1,162 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpBaseNode.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.Buffers;
using System;
using System.Collections.Generic;
using System.Text;
namespace StgSharp.Script.Express
{
public abstract class ExpBaseNode : IASTNode<ExpBaseNode, IExpElementSource>
{
protected internal ExpNodeFlag _nodeFlag;
protected internal string _name;
protected ExpBaseNode( string name, ExpSchema context )
{
_name = name;
NameSpace = context;
Next = this;
Previous = this;
}
public bool IsNumber
{
get { return ( _nodeFlag | ExpNodeFlag.BuiltinType_Number ) != 0; }
}
public abstract ExpBaseNode Left
{
get;
}
public static ExpBaseNode Empty
{
get => ExpEmptyNode._only;
}
public ExpBaseNode Next
{
get;
set;
}
public abstract ExpBaseNode Right
{
get;
}
public ExpBaseNode Previous
{
get;
set;
}
public ExpSchema NameSpace
{
get;
private set;
}
public abstract IExpElementSource EqualityTypeConvert
{
get;
}
public long NodeFlag => ( long )_nodeFlag;
public string CodeConvertTemplate
{
get;
internal set;
}
public string Name => _name;
public virtual void AppendNode( ExpBaseNode nextToken )
{
Next.Previous = nextToken;
nextToken.Next = Next;
Next = nextToken;
Next.Previous = this;
}
public ExpNodeNextEnumerator GetEnumerator()
{
return new ExpNodeNextEnumerator( this );
}
public static bool IsNullOrEmpty( ExpBaseNode node )
{
return node == ExpEmptyNode._only || node == null;
}
public static bool VerifyTypeConvertable(
ExpBaseNode left,
ExpBaseNode right )
{
IExpElementSource tLeft = left.EqualityTypeConvert,
tRight = right.EqualityTypeConvert;
if( tLeft == null || tRight == null ) {
return false;
}
return tLeft.IsConvertable( tRight );
}
protected void AssertSchemaInclude( ExpBaseNode expressionRoot )
{
if( expressionRoot.NameSpace != NameSpace && NameSpace.TryGetSchemaInclude(
expressionRoot.NameSpace.Name, out _ ) ) {
throw new ExpInvalidSchemaIncludeException(
NameSpace, expressionRoot.NameSpace );
}
}
private class ExpEmptyNode : ExpBaseNode
{
internal static readonly ExpEmptyNode _only = new();
public ExpEmptyNode()
: base( string.Empty, ExpSchema.BuiltinSchema ) { }
public override ExpBaseNode Left => _only;
public override ExpBaseNode Right => _only;
public override ExpInstantiableElementBase EqualityTypeConvert => ExpInstantiableElementBase.Void;
}
}
}
@@ -0,0 +1,74 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpCallProcedureNode.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.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Script.Express
{
public class ExpCallProcedureNode : ExpNode
{
private ExpNode _params;
public ExpCallProcedureNode( Token source, ExpProcedure caller, ExpNode param ) : base( source )
{
_params = param;
CalledProcedure = caller;
}
public override ExpNode Left => Empty;
public override ExpNode Right => _params;
public ExpProcedure CalledProcedure { get; init; }
public override IExpElementSource EqualityTypeConvert => ExpInstantiableElement.Void;
public static ExpCallProcedureNode CallProcedure( Token postion, ExpProcedure caller, ExpNode input )
{
ExpCallProcedureNode node = new ExpCallProcedureNode( postion, caller, input )
{
/*
* 0. parameters
*/
CodeConvertTemplate = $$"""
{{caller.Name}}( {0} )
"""
};
return node;
}
}
}
@@ -0,0 +1,59 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpElementInstanceNode.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 class ExpElementInstanceNode : ExpNode
{
private ExpInstantiableElement _element;
public ExpElementInstanceNode(
Token source,
ExpInstantiableElement element )
: base( source )
{
_element = element;
}
public override ExpInstantiableElement EqualityTypeConvert => _element;
public override ExpNode Left => Empty;
public override ExpNode Right => Empty;
}
}
@@ -0,0 +1,76 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpIndexOfNode.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 class ExpIndexOfNode : ExpNode
{
private ExpCollectionInstanceBase _collection;
private ExpNode _indexExpression;
private ExpIndexOfNode(
Token source,
ExpCollectionInstanceBase instance,
ExpNode indexExpression )
: base( source )
{
_collection = instance;
_indexExpression = indexExpression;
CodeConvertTemplate = @"{0}[{1}]";
}
public override ExpNode Left => _collection;
public override ExpNode Right => _indexExpression;
public override IExpElementSource EqualityTypeConvert => _collection.EqualityTypeConvert;
public static ExpIndexOfNode Create(
Token source,
ExpCollectionInstanceBase instance,
ExpNode indexExpression )
{
if( !indexExpression.IsNumber ) {
throw new ExpInvalidTypeException(
"Number", indexExpression.EqualityTypeConvert.Name );
}
return new ExpIndexOfNode( source, instance, indexExpression );
}
}
}
@@ -0,0 +1,157 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpLiteralGenericNode.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.Data;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace StgSharp.Script.Express
{
public class ExpIntNode : ExpElementInstanceBase
{
private int _value;
public ExpIntNode( Token source, int value )
: base( source )
{
_value = value;
_nodeFlag = ExpNodeFlag.BuiltinType_Int | ExpNodeFlag.Element_Type;
}
public override IExpElementSource EqualityTypeConvert => ExpSchema.BuiltinSchema
.TryGetType(
ExpCompile.KeyWord.Int, out ExpTypeSource? type ) ?
type : throw new ExpCompileNotInitializedException();
public int Value => _value;
public override string TypeName => ExpCompile.KeyWord.Int;
}
public class ExpStringNode : ExpElementInstanceBase
{
private readonly string _value;
public ExpStringNode( Token source, string value )
: base( source )
{
_value = value;
_nodeFlag = ExpNodeFlag.BuiltinType_String | ExpNodeFlag.Element_Type;
}
public override IExpElementSource EqualityTypeConvert => ExpSchema.BuiltinSchema
.TryGetType(
ExpCompile.KeyWord.String,
out ExpTypeSource? type ) ?
type : throw new ExpCompileNotInitializedException();
public override string TypeName => EqualityTypeConvert.Name;
public string Value => _value;
}
public class ExpBoolNode : ExpElementInstanceBase
{
private readonly bool _value;
public ExpBoolNode( Token source, bool value )
: base( source )
{
_value = value;
_nodeFlag = ExpNodeFlag.BuiltinType_Boolean | ExpNodeFlag.Element_Type;
}
public bool Value => _value;
public override IExpElementSource EqualityTypeConvert => ExpSchema.BuiltinSchema
.TryGetType(
ExpCompile.KeyWord.Bool, out ExpTypeSource? type ) ?
type : throw new ExpCompileNotInitializedException();
public override string TypeName => EqualityTypeConvert.Name;
}
public class ExpRealNumberNode : ExpElementInstanceBase
{
private readonly float _value;
public ExpRealNumberNode( Token source, float value )
: base( source )
{
_value = value;
_nodeFlag = ExpNodeFlag.BuiltinType_Real | ExpNodeFlag.Element_Type;
}
public float Value => _value;
public override IExpElementSource EqualityTypeConvert => ExpSchema.BuiltinSchema
.TryGetType(
ExpCompile.KeyWord.String,
out ExpTypeSource? type ) ?
type : throw new ExpCompileNotInitializedException();
public override string TypeName => EqualityTypeConvert.Name;
}
public class ExpLogicValueNode : ExpElementInstanceBase
{
private readonly ExpLogic _value;
public ExpLogicValueNode( Token source, ExpLogic value )
: base( source )
{
_value = value;
_nodeFlag = ExpNodeFlag.BuiltinType_Logic | ExpNodeFlag.Element_Type;
}
public ExpLogic Value => _value;
public override IExpElementSource EqualityTypeConvert => ExpSchema.BuiltinSchema
.TryGetType(
ExpCompile.KeyWord.Logic,
out ExpTypeSource? type ) ?
type : throw new ExpCompileNotInitializedException();
public override string TypeName => EqualityTypeConvert.Name;
}
}
@@ -0,0 +1,104 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpElementInstanceBase.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.Runtime.CompilerServices;
using System.Text;
namespace StgSharp.Script.Express
{
[Flags]
public enum ExpElementType : int
{
Void = 0,
Const = 1,
Entity = 2,
Type = 4,
Function = 8,
Section = 16,
Expression = 32,
Rule = 64,
Procedure = 128,
Collection = 256,
}
public abstract class ExpElementInstanceBase : ExpNode
{
protected ExpElementInstanceBase( Token source )
: base( source )
{
CodeConvertTemplate = source.Value;
}
public ExpElementType ElementType { get; }
public override ExpNode Left => Empty;
public override ExpNode Right => Empty;
public abstract string TypeName { get; }
public static ExpElementInstanceBase CreateLiteral( Token t )
{
if( int.TryParse( t.Value, out int _int ) )
{
return new ExpIntNode( t, _int );
} else if( float.TryParse( t.Value, out float _float ) )
{
return new ExpRealNumberNode( t, _float );
} else if( bool.TryParse( t.Value, out bool _bool ) )
{
return new ExpBoolNode( t, _bool );
} else if( ExpLogic.TryParse( t.Value, out ExpLogic _logic ) )
{
return new ExpLogicValueNode( t, _logic );
} else
{
return new ExpStringNode( t, t.Value );
}
}
public ExpInstanceReferenceNode MakeReference( Token t )
{
return new ExpInstanceReferenceNode( t, this );
}
public bool TryGetMember( string name, out ExpNode node )
{
return EqualityTypeConvert.TryGetMember( name, out node );
}
}
}
@@ -0,0 +1,42 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpNodeGenerator.BranchParser.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 ExpNodeGenerator { }
}
@@ -0,0 +1,69 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpNodeGenerator.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 ExpNodeGenerator
{
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,55 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpErrorThrow.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 ExpNodeGenerator
{
public void ThrowCompileException( int errorCode )
{
switch( errorCode ) {
case 0 or 1:
return;
case TokenTypeNotMatch:
throw new Exception();
default:
break;
}
}
}
}
@@ -0,0 +1,102 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpNodeGenerator.FunctionCalling.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 static StgSharp.Script.Express.ExpCompile;
namespace StgSharp.Script.Express
{
public partial class ExpNodeGenerator
{
private bool _isCallingFunction = false;
private List<CompileDepthMark> _funcCallDepthCount = new List<CompileDepthMark>(
);
private void EnterFunctionCalling()
{
_isCallingFunction = true;
CompileDepthMark mark = _cache.IncreaseDepth();
_funcCallDepthCount.Add( mark );
}
private void ExitFunctionCalling()
{
CompileDepthMark mark = _funcCallDepthCount.Last();
if( _funcCallDepthCount.Count == 0 ) {
_isCallingFunction = false;
}
}
//checking _operandAheadOfDepth can be used to check if the function calling has no param.
//put one of param to tail of function calling pram expression node
/// <summary>
/// Compile a parameter expression and add it to head of function parameter node list.
/// </summary>
private void MergeFunctionCallingParameter( Token currentSeparator )
{
if( _cache.OperandAheadOfDepth == 1 ) {
if( _cache.PopOperand( out Token t, out ExpNode? n ) ) {
n!.PrependNode( ExpNode.NonOperation( currentSeparator ) );
} else {
switch( t.Flag ) {
case TokenFlag.Number:
if( int.TryParse( t.Value, out int intVal ) ) {
n = new ExpIntNode( t, intVal );
} else if( float.TryParse(
t.Value, out float floatVal ) ) {
n = new ExpRealNumberNode( t, floatVal );
}
break;
case TokenFlag.String:
n = new ExpStringNode( t, t.Value );
break;
case TokenFlag.Member:
// case1: name of a _instance, make ref copy
// case2: name of a function, make a function call
// case3: unknown, make a _instance member node, check while link
break;
default:
break;
}
}
} else {
//TODO compile the param expression
}
}
}
}
@@ -0,0 +1,104 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpNodeGenerator.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 ExpKeyword = StgSharp.Script.Express.ExpressCompile.Keyword;
namespace StgSharp.Script.Express
{
public partial class ExpNodeGenerator
{
private bool TryParseIfExpression( 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 ) { } 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 ) { } 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 )
{
//no else occur
} else if( state.CurrentState == ExpKeyword.Else )
{
// else occur
} else
{
throw new ExpCompileException(
t,
$"Keyword {t.Value} should be after keyword {ExpKeyword.Then} or {ExpKeyword.Else}" );
}
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; }
}
}
}
@@ -0,0 +1,101 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpNodeGenerator.Operator.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 ExpNodeGenerator
{
public int CompareOperatorPrecedence( Token left, Token right )
{
ExpCompile.TryGetOperatorPrecedence(
left.Value, out int leftPrecedence );
ExpCompile.TryGetOperatorPrecedence(
right.Value, out int rightPrecedence );
return leftPrecedence - rightPrecedence;
}
public bool TryGenerateBinaryNode( Token t, out ExpNode node )
{
ExpNode left = GetNextOperandCache();
ExpNode right = GetNextOperandCache();
switch( t.Value ) {
case ExpCompile.KeyWord.Add:
node = ExpBinaryOperatorNode.Add( t, left, right );
return true;
case ExpCompile.KeyWord.Sub:
node = ExpBinaryOperatorNode.Sub( t, left, right );
return true;
case ExpCompile.KeyWord.Mul:
node = ExpBinaryOperatorNode.Mul( t, left, right );
return true;
case ExpCompile.KeyWord.Div:
node = ExpBinaryOperatorNode.Div( t, left, right );
return true;
case ExpCompile.KeyWord.Equal:
node = ExpBinaryOperatorNode.EqualTo( t, left, right );
return true;
case ExpCompile.KeyWord.NotEqual:
node = ExpBinaryOperatorNode.NotEqualTo( t, left, right );
return true;
default:
node = ExpNode.Empty;
return false;
}
}
public bool TryGenerateUnaryNode( Token t, out ExpNode node )
{
ExpNode operand = GetNextOperandCache();
switch( t.Value ) {
case ExpCompile.KeyWord.UnaryPlus:
node = ExpUnaryOperatorNode.UnaryPlus( t, operand );
return true;
case ExpCompile.KeyWord.UnaryMinus:
node = ExpUnaryOperatorNode.UnaryMinus( t, operand );
return true;
case ExpCompile.KeyWord.Not:
node = ExpUnaryOperatorNode.UnaryNot( t, operand );
return true;
default:
node = ExpNode.Empty;
return false;
}
}
}
}
@@ -0,0 +1,163 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpNodeGenerator.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 ExpNodeGenerator
{
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,92 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpNodeGenerator.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 ExpNodeGenerator
{
private void ClosePrefixReverse( Token rightSeparator )
{
Token op;
while( _cache.TryPopOperator( out op ) )
{
if( op.Value == ExpKeyword.Comma )
{
if( !_cache.TryPopOperand( out bool isNode, out Token t1, out ExpNode? n1 ) ) {
throw new ExpCompileException( op, "No expression before a comma" );
}
if( !isNode )
{
//On some occasions, a token may found,
//but the processor is not implemented
throw new NotImplementedException();
}
if( !_cache.TryPopOperand( out isNode, out Token t2, out ExpNode? n2 ) ) {
throw new ExpCompileException( op, "No expression before a comma" );
}
if( !isNode )
{
//On some occasions, a token may found,
//but the processor is not implemented
throw new NotImplementedException();
}
n1.PrependNode( n2 );
_cache.PushOperand( n1 );
continue;
}
ConvertAndPushOneOperator( op );
}
if( !_cache.TryPopOperand( out _, out _, out ExpNode? root ) ) {
_cache.PushOperand( ExpNode.Empty );
}
_cache.DecreaseDepth();
if( IsSeparatorMatch( _cache.PeekOperator(), rightSeparator ) )
{
_cache.PopOperator();
_cache.PushOperand( root );
} else
{
throw new ExpCompileException(
rightSeparator, "Ending of block soes not match its begging" );
}
}
}
}
@@ -0,0 +1,187 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpNodeGenerator.StateCommon.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.ExpCompile.KeyWord;
namespace StgSharp.Script.Express
{
public partial class ExpNodeGenerator
{
private void AppendToken_Common( Token t )
{
switch( t.Flag ) {
// operand, check precedence and push
case TokenFlag.Symbol_Unary or TokenFlag.Symbol_Binary:
int cmp = -1;
processPrecedence:
Token tmp = _cache.PeekOperator();
cmp = CompareOperatorPrecedence( t, tmp );
if( cmp <= 0 ) {
ConvertOneOperator();
goto processPrecedence;
}
_cache.PushOperand( t );
break;
// literal, construct and push
case TokenFlag.Number or TokenFlag.String:
_cache.PushOperand( t );
break;
// instance ref, make ref and push
// function call, push as operator
// keyword, call TryParseConstant method to process
// name of member in instance, parse as MemberNameNode
case TokenFlag.Member:
if( _context.TryGetFunction( t.Value, out _ ) ) {
_cache.PushOperator( t );
} else if( _local.TryGetMember( t.Value,
out ExpNode? node ) ) {
if( node is ExpElementInstanceBase instance ) {
_cache.PushOperand( instance.MakeReference( t ) );
return;// ref of an instance
}
} else if( TryParseConstant( t ) ) {
return;
} else if( TryParseFunction( t ) ) {
return;
} else if( TryParseBranch( t ) ) {
return;
} else {
_cache.PushOperand( t );
}
break;
case TokenFlag.Separator_Single: //a , ; found
// if operator stack is not empty, convert all operators to node until meet a same separator
// or OperandAheadOfSeparator property is less than certain value
_cache.PushOperator( t );
break;
case TokenFlag.Separator_Left: //a ( [ { found
// check if the last token is a function name, loop block or branch
_cache.PushOperator( t );
break;
case TokenFlag.Separator_Right: //a } ] ) found
//Convert operator until meet a matched separator
while( _cache.TryPopOperator( out Token op ) ) {
if( IsSeparatorMatch( t, op ) ) {
if( _cache.OperatorAheadOfDepth == 0 ) {
_cache.TryPeekOperand(
out _, out Token tOperand,
out ExpNode nOperand );
return;
}
} else {
return;
}
}
break;
case TokenFlag.Index_Left: // a [ found
_cache.PushOperand( t );
return;
case TokenFlag.Index_Right: // a ] found
while( _cache.TryPopOperator( out Token op ) ) {
if( op.Value == ExpKeyWord.IndexOf ) { } else { }
}
break;
default:
break;
}
}
private bool IsSeparatorMatch( Token source, Token target )
{
return source.Value switch
{
ExpKeyWord.LeftBrace => target.Value == ExpKeyWord.RightBrace,
ExpKeyWord.LeftParen => target.Value == ExpKeyWord.RightParen,
ExpKeyWord.Comma => target.Value == ExpKeyWord.Comma,
ExpKeyWord.Semicolon => target.Value == ExpKeyWord.Semicolon,
_ => false
};
}
private bool TryParseBranch( Token t )
{
if( t.Value == ExpKeyWord.Case ) {
_cache.PushOperator( t );
_cache.IncreaseDepth( ( int )StateCode.CaseBranch );
return true;
} else if( t.Value == ExpKeyWord.If ) {
_cache.PushOperator( t );
_cache.IncreaseDepth( ( int )StateCode.IfBranch );
return true;
} else if( t.Value == ExpKeyWord.Repeat ) {
_cache.PushOperator( t );
_cache.IncreaseDepth( ( int )StateCode.RepeatLoop );
return true;
}
return false;
}
private bool TryParseConstant( Token t )
{
if( t.Value == ExpKeyWord.True ) {
_cache.PushOperand( new ExpBoolNode( t, true ) );
return true;
} else if( t.Value == ExpKeyWord.False ) {
_cache.PushOperand( new ExpBoolNode( t, false ) );
return true;
}
return false;
}
private bool TryParseFunction( Token t )
{
if( ExpKeyWord.BuiltinFunctions.Contains( t.Value ) ) {
_cache.PushOperator( t );
_cache.IncreaseDepth( ( int )StateCode.FunctionCalling );
return true;
} else if( _context.TryGetFunction(
t.Value, out ExpFunctionSource? f ) ) {
_cache.PushOperand( t );
_cache.IncreaseDepth( ( int )StateCode.FunctionCalling );
return true;
}
return false;
}
}
}
@@ -0,0 +1,103 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpNodeGenerator.StateFunctionCalling.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 static StgSharp.Script.Express.ExpCompile;
namespace StgSharp.Script.Express
{
public partial class ExpNodeGenerator
{
private bool _isCallingFunction = false;
private List<CompileDepthMark> _funcCallDepthCount = new List<CompileDepthMark>(
);
private void EnterFunctionCalling()
{
_isCallingFunction = true;
CompileDepthMark mark = _cache.IncreaseDepth(
( int )StateCode.FunctionCalling );
_funcCallDepthCount.Add( mark );
}
private void ExitFunctionCalling()
{
CompileDepthMark mark = _funcCallDepthCount.Last();
if( _funcCallDepthCount.Count == 0 ) {
_isCallingFunction = false;
}
}
//checking _operandAheadOfDepth can be used to check if the function calling has no param.
//put one of param to tail of function calling pram expression node
/// <summary>
/// Compile a parameter expression and add it to head of function parameter node list.
/// </summary>
private void MergeFunctionCallingParameter( Token currentSeparator )
{
if( _cache.OperandAheadOfDepth == 1 ) {
if( _cache.PopOperand( out Token t, out ExpNode? n ) ) {
n!.PrependNode( ExpNode.NonOperation( currentSeparator ) );
} else {
switch( t.Flag ) {
case TokenFlag.Number:
if( int.TryParse( t.Value, out int intVal ) ) {
n = new ExpIntNode( t, intVal );
} else if( float.TryParse(
t.Value, out float floatVal ) ) {
n = new ExpRealNumberNode( t, floatVal );
}
break;
case TokenFlag.String:
n = new ExpStringNode( t, t.Value );
break;
case TokenFlag.Member:
// case1: name of a _instance, make ref copy
// case2: name of a function, make a function call
// case3: unknown, make a _instance member node, check while link
break;
default:
break;
}
}
} else {
//TODO compile the param expression
}
}
}
}
@@ -0,0 +1,78 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpNodeGenerator.StateManage.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.Frozen;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Script.Express
{
public partial class ExpNodeGenerator
{
private CompileState _state = CompileState.Common;
private int _lbToken = 0; // [ count
private int _lcbCount = 0; // { count
private int _lpCount = 0; // ( count
private void ProcessLeftSeparator( Token t )
{
switch( t.Value ) {
case "[":
_lbToken++;
break;
case "{":
_lcbCount++;
break;
case "(":
_lpCount++;
break;
default:
break;
}
}
private enum CompileState
{
Common,
FunctionCalling,
Branch,
Loop,
}
}
}
@@ -0,0 +1,259 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpNodeGenerator.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 ExpNodeGenerator
{
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;
}
processOperator:
if( _cache.OperatorAheadOfDepth == 0 )
{
if( _cache.OperandAheadOfDepth == 1 )
{
if( _cache.Depth != 1 )
{
_cache.DecreaseDepth();
if( _cache.PeekOperator().Value == t.Value )
{
_cache.PopOperand( out _, out ExpNode? currentExpression );
_cache.PopOperand( out Token valToken, out _ );
_cache.PopOperand( out _, out ExpNode? previousExpression );
currentExpression.PrependNode( previousExpression );
_cache.PushOperand( previousExpression );
}
}
_cache.PushOperand( t );
_cache.PushOperator( t );
_cache.IncreaseDepth( ( int )ExpCompileStateCode.Common );
return true;
} else
{
ExpInvalidSyntaxException.ThrowNoOperator( t );
}
}
Token op;
if( _cache.TryPopOperator( out op ) )
{
if( op.Value == t.Value )
{
_cache.PopOperand( out _, out ExpNode? node );
//append node to tail
_cache.PushOperand( t );
_cache.PushOperator( t );
} else
{
ExpNode node = ConvertAndPushOneOperator( op );
goto processOperator;
}
}
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.PrefixSeparator );
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;
}
}
}
+180
View File
@@ -0,0 +1,180 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpNodeGenerator.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 ExpNodeGenerator
{
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 ExpNodeGenerator()
{
_cache = new CompileStack<ExpNode, IExpElementSource>();
}
public ExpNodeGenerator( 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 )_cache.CurrentDepthMark.Usage )
{
case ExpCompileStateCode.Common:
AppendToken_common( expToken );
break;
default:
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 { }
throw new NotImplementedException();
}
private bool TryParseBranch( Token t )
{
if( t.Value == ExpKeyword.Case )
{
_cache.PushOperator( t );
_cache.IncreaseDepth( ( int )ExpCompileStateCode.CaseBranch );
return true;
} else if( t.Value == ExpKeyword.If )
{
_cache.PushOperator( t );
_cache.IncreaseDepth( ( int )ExpCompileStateCode.IfBranch );
return true;
} else if( t.Value == ExpKeyword.Repeat )
{
_cache.PushOperator( t );
_cache.IncreaseDepth( ( int )ExpCompileStateCode.RepeatLoop );
return true;
}
return false;
}
/**/
public enum ExpCompileStateCode
{
Common,
ForLoop,
RepeatLoop,
UntilLoop,
IfBranch,
CaseBranch,
PrefixSeparator,
MiddleSeparator,
CollectionIndex,
}
}
}
@@ -0,0 +1,140 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpNodeNextEnumerator.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 System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Script.Express
{
public static class ExpNodeNextEnumeratorExtensions
{
public static ExpNodeNextEnumerator AsCollectionEnumerator( this ExpSyntaxNode token )
{
ExpNodeNextEnumerator enumerator = new ExpNodeNextEnumerator( token );
IExpElementSource type = token.EqualityTypeConvert;
while( enumerator.MoveNext() )
{
if( enumerator. Current != type ) {
throw new InvalidCastException();
}
}
return enumerator;
}
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public static ExpNodeNextEnumerator ToEnumerator( this ExpSyntaxNode token )
{
return new ExpNodeNextEnumerator( token );
}
}
public class ExpNodeNextEnumerator : IEnumerator<ExpSyntaxNode>
{
private ExpSyntaxNode _current;
private List<ExpSyntaxNode> _begin = new List<ExpSyntaxNode>();
public ExpNodeNextEnumerator( ExpSyntaxNode token )
{
_begin[ 0 ] = token;
_current = token;
ExpSyntaxNode t = token;
while( !ReferenceEquals( t.Next, token ) && t.Next != null )
{
t = t.Next;
_begin.Add( t );
}
}
public ExpSyntaxNode this[ int index ]
{
get
{
ArgumentOutOfRangeException.ThrowIfNegative( index );
ArgumentOutOfRangeException.ThrowIfGreaterThan( index, _begin.Count );
return _begin[ index ];
}
}
public ExpSyntaxNode Current => _current;
public List<ExpSyntaxNode> Values => _begin;
public void AssertEnumeratorCount( int count )
{
if( _begin.Count != count ) {
throw new InvalidOperationException(
$"Enumerator count mismatch. Expected {count}, but got {_begin.Count}." );
}
}
public void AssertEnumeratorCount( int min, int max )
{
if( _begin.Count < min || _begin.Count > max ) {
throw new InvalidOperationException(
$"Enumerator count mismatch. Expected between {min} and {max}, but got {_begin.Count}." );
}
}
public bool MoveNext()
{
ExpSyntaxNode next = _current.Next;
if( ReferenceEquals( next, _begin ) || next == null ) {
return false;
}
_current = next;
return true;
}
void IDisposable.Dispose()
{
return;
}
void IEnumerator.Reset()
{
_current = _begin[ 0 ];
}
object IEnumerator.Current => _current;
}
}
+427
View File
@@ -0,0 +1,427 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// 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.HighPerformance;
using System;
using System.Linq;
using System.Text.RegularExpressions;
namespace StgSharp.Script.Express
{
public partial class ExpSourceReader : IScriptTokenReader
{
private const int
MultiLineEnd = 0x0029002A; // *)
private const string TokenMark = "token", EndMark = "end", RestMark = "rest";
private bool _isReadingMultiLineComment;
private int _current, _lineNum;
private IScriptSourceProvider _provider;
private Regex
_nextHashtagSymbolPattern = GetHashtagSymbolPattern() ,
_nextWordTokenPattern = GetNextWordTokenPattern(),
_nextStringLiteralPattern = GetStringLiteralPattern(),
_nextNumberLiteralPattern = GetNumberLiteralPattern(),
_nextStringLiteralPatternWithSingle = GetStringLiteralPatternWithSingle(),
_skipBlankPattern = GetSkipBlankPattern(),
_nextSymbolPattern = GetSymbolPattern();
private string _lineCache;
private Token _last;
public ExpSourceReader( IScriptSourceProvider provider )
{
_provider = provider;
_current = 0;
_lineCache = string.Empty;
_isReadingMultiLineComment = false;
}
public bool IsEmpty
{
get => ( ( string.IsNullOrEmpty( _lineCache ) || _current >= _lineCache.Length ) ) && _provider.IsEmpty;
}
public int LineNumber
{
get => _provider.Location;
}
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
{
_lineCache = _provider.ReadLine( out _lineNum );
} while (string.IsNullOrEmpty( _lineCache ));
_current = 0;
}
if( _isReadingMultiLineComment )
{
int index;
fixed( char* cPtr = _lineCache.AsSpan( _current ) ) {
index = UnsafeCompute.IndexOfCharPair(
cPtr, MultiLineEnd, _lineCache.Length );
}
if( index == -1 )
{
_lineCache = string.Empty;
} else
{
_isReadingMultiLineComment = false;
_current += index + 2;
}
}
lineOver = string.IsNullOrEmpty( _lineCache ) || _current >= _lineCache.Length;
}
return _lineCache.AsSpan().Slice( _current );
}
public unsafe Token ReadToken()
{
int begin, end, rest;
readLine:
ReadOnlySpan<char> source;
if( !TryReadLine( out source ) ) {
return Token.Empty;
}
char c = source[ 0 ];
if( char.IsLetter( c ) )
{
Match match = _nextWordTokenPattern.Match( _lineCache, _current );
if( match.Success )
{
begin = match.Groups[ TokenMark ].Index;
end = match.Groups[ EndMark ].Index;
rest = match.Groups[ RestMark ].Index;
_current = rest;
_last = new(
ExpressCompile.PoolString( source[ ..( end - begin ) ] ), _lineNum, begin,
TokenFlag.Member );
return _last;
} else
{
throw new ExpInvalidCharException( _current );
}
} else if( char.IsPunctuation( c ) || char.IsSymbol( c ) )
{
Match match;
switch( c )
{
case '#':
match = _nextHashtagSymbolPattern.Match( _lineCache, _current );
if( match.Success )
{
begin = match.Groups[ "token" ].Index;
end = match.Groups[ "end" ].Index;
rest = match.Groups[ "rest" ].Index;
_current = rest;
_last = new(
ExpressCompile.PoolString( source[ 1..( end - begin ) ] ), _lineNum,
begin, TokenFlag.Member );
return _last;
} else
{
throw new ExpInvalidCharException( '#' );
}
case '\'':
char cNext = source[ 1 ];
if( cNext == '\'' ) //empty string
{
begin = _current;
_current += 2;
return new( string.Empty, _lineNum, begin, TokenFlag.String );
}
match = _nextStringLiteralPatternWithSingle.Match( _lineCache, _current );
if( match.Success )
{
begin = match.Groups[ "token" ].Index;
end = match.Groups[ "end" ].Index;
rest = match.Groups[ "rest" ].Index;
_current = rest;
_last = new(
ExpressCompile.PoolString( source[ 1..( end - begin ) ] ), _lineNum,
begin, TokenFlag.String );
return _last;
} else
{
throw new ExpInvalidCharException( '\"' );
}
case '"':
cNext = source[ 1 ];
if( cNext == '\"' ) //empty string
{
begin = _current;
_current += 2;
return new( string.Empty, _lineNum, begin, TokenFlag.String );
}
match = _nextStringLiteralPattern.Match( _lineCache, _current );
if( match.Success )
{
begin = match.Groups[ "token" ].Index;
end = match.Groups[ "end" ].Index;
rest = match.Groups[ "rest" ].Index;
_current = rest;
_last = new(
ExpressCompile.PoolString( source[ 1..( end - begin ) ] ), _lineNum,
begin, TokenFlag.String );
return _last;
} else
{
throw new ExpInvalidCharException( '\"' );
}
case '(':
cNext = source[ 1 ];
if( cNext == '*' )
{
_isReadingMultiLineComment = true;
_current += 2;
goto readLine;
} else
{
begin = _current;
_current++;
_last = new(
ExpressCompile.PoolString( source[ ..1 ] ), _lineNum, begin,
TokenFlag.Separator_Left );
return _last;
}
case ')' or '}':
begin = _current;
_current++;
_last = new Token(
ExpressCompile.PoolString( source[ ..1 ] ), _lineNum, begin,
TokenFlag.Separator_Right );
return _last;
case '-':
// 1. - number
// 2. -- comment
// 3. - number type param(UNARY)
// 4. param - param(BINARY)
cNext = source[ 1 ];
if( char.IsNumber( cNext ) )
{
match = _nextNumberLiteralPattern.Match( _lineCache, _current );
if( match.Success )
{
begin = match.Groups[ TokenMark ].Index;
end = match.Groups[ EndMark ].Index;
rest = match.Groups[ RestMark ].Index;
_current = rest;
return new(
ExpressCompile.PoolString( source[ ..( end - begin ) ] ),
_lineNum, begin, TokenFlag.Number );
} else
{
throw new ExpInvalidCharException( _current );
}
} else if( cNext == '-' )
{
_lineCache = string.Empty;
_current = 0;
goto readLine;
} else
{
begin = _current;
_current++;
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++;
_last = new Token(
ExpressCompile.PoolString( "{" ), _lineNum, begin,
TokenFlag.Separator_Left );
return _last;
case '[':
begin = _current;
_current++;
_last = new Token(
ExpressCompile.PoolString( "[" ), _lineNum, begin,
TokenFlag.Index_Left );
return _last;
case ']':
begin = _current;
_current++;
_last = new Token(
ExpressCompile.PoolString( "]" ), _lineNum, begin,
TokenFlag.Index_Right );
return _last;
case ';' or ',':
begin = _current;
_current++;
_last = new Token(
ExpressCompile.PoolString( source[ ..1 ] ), _lineNum, begin,
TokenFlag.Separator_Middle );
return _last;
case ':':
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 )
{
_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 );
}
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++;
_last = new Token(
ExpressCompile.Keyword.Equal, _lineNum, begin,
TokenFlag.Symbol_Binary );
return _last;
default:
throw new ExpInvalidCharException( c );
}
} else if( char.IsNumber( c ) )
{
Match match = _nextNumberLiteralPattern.Match( _lineCache, _current );
if( match.Success )
{
begin = match.Groups[ TokenMark ].Index;
end = match.Groups[ EndMark ].Index;
rest = match.Groups[ RestMark ].Index;
_current = rest;
string str = ExpressCompile.PoolString( source[ ..( end - begin ) ] );
return new( str, _lineNum, begin, TokenFlag.Number );
} else
{
throw new ExpInvalidCharException( _current );
}
} else if( char.IsWhiteSpace( c ) )
{
Match match = _skipBlankPattern.Match( _lineCache, _current );
if( match.Success )
{
rest = match.Groups[ RestMark ].Index;
_current = rest;
goto readLine;
} else
{
throw new ExpInvalidCharException( _current );
}
} else
{
throw new ExpInvalidCharException( c );
}
}
public bool TryReadLine( out ReadOnlySpan<char> line )
{
line = ReadLine();
return line != ReadOnlySpan<char>.Empty;
}
public bool TryReadToken( out Token t )
{
t = ReadToken();
return !IsEmpty;
}
[GeneratedRegex(
@"(?<token>#[0-9A-Za-z]+)(?<end>\s*?)(?<rest>\S|$)",
RegexOptions.Singleline )]
private static partial Regex GetHashtagSymbolPattern();
[GeneratedRegex(
@"(?<token>[a-zA-Z][a-zA-Z0-9_]*)(?<end>\s*?)(?<rest>\S|$)",
RegexOptions.Singleline )]
private static partial Regex GetNextWordTokenPattern();
[GeneratedRegex(
@"(?<token>-?\s*?[0-9]+(?:\.[0-9]*)?E?(?:[+-]?[0-9]+)?)(?<end>\s*?)(?<rest>\S|$)",
RegexOptions.Singleline )]
private static partial Regex GetNumberLiteralPattern();
[GeneratedRegex( @"(?:\s+?)(?<rest>\S|$)", RegexOptions.Singleline )]
private static partial Regex GetSkipBlankPattern();
[GeneratedRegex(
@"(?<token>"")(?>\\\\|\\""|(?!')[^""])*(?<end>""|$)\s*?(?<rest>\S|$)",
RegexOptions.Singleline )]
private static partial Regex GetStringLiteralPattern();
[GeneratedRegex(
@"(?<token>')(?>\\\\|\\'|''|(?!')[^'])*(?<end>')\s*?(?<rest>\S|$)",
RegexOptions.Singleline )]
private static partial Regex GetStringLiteralPatternWithSingle();
[GeneratedRegex(
@"(?<token>[:<>=+\-*\/]+)(?<end>\s?)\s*?(?<rest>\S|$)",
RegexOptions.Singleline )]
private static partial Regex GetSymbolPattern();
}
}
@@ -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 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;
ExpSyntaxNode root;
if( _cache.OperatorAheadOfDepth == 0 )
{
if( _cache.OperandAheadOfDepth == 1 )
{
_cache.PopOperand( out _, out ExpSyntaxNode? statement );
_cache.StatementsInDepth.Push( statement );
} else
{
_cache.StatementsInDepth.Push( ExpSyntaxNode.Empty );
}
} else
{
while( _cache.TryPopOperator( out op ) ) {
ConvertAndPushOneOperator( op );
}
_cache.PopOperand( out _, out root );
_cache.StatementsInDepth.Push( root );
}
root = _cache.PackAllStatements();
if( rightSeparator.Value == ")" ) {
root = ExpTupleNode.Pack( root );
}
_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,262 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// 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 Microsoft.CodeAnalysis.CSharp.Syntax;
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;
}
if( TryParseKeyword( 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;
} else if( _tempVariableInLoops.TryGetValue( t.Value, out instance! ) )
{
_cache.PushOperand( ExpInstanceReferenceNode.MakeReferenceFrom( t, instance ) );
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;
}
}
}
}
@@ -0,0 +1,48 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="IExpMarshalType.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 interface IExpMarshalType<TSelf> where TSelf: class
{
static virtual TSelf Create( string name, ExpSyntaxNode node )
{
return null;
}
}
}
@@ -0,0 +1,55 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpErrorThrow.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 ExpNodeGenerator
{
public void ThrowCompileException( int errorCode )
{
switch( errorCode ) {
case 0 or 1:
return;
case TokenTypeNotMatch:
throw new Exception();
default:
break;
}
}
}
}
@@ -0,0 +1,173 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpNodeGenerator.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.Threading;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Script.Express
{
public partial class ExpNodeGenerator
{
private const int EndLine = 1;
private const int TokenGenerated = 0;
private const int TokenTypeNotMatch = -1;
private ExpNode _lastStatement;
private GeneratedExpSchema _context;
private IExpElementSource _local;
private List<ExpNode> _cache;
private Stack<TokenNodeStack<ExpNode, IExpElementSource>> _operands;
private Stack<ExpNode> _operandsNode;
private Stack<Token> _operandsToken;
private Stack<Token> _operators;
public ExpNodeGenerator()
{
_operators = new Stack<Token>();
_operands = new Stack<TokenNodeStack<ExpNode, IExpElementSource>>();
}
private TokenNodeStack<ExpNode, IExpElementSource> CurrentOperands => _operands.Peek(
);
/// <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( Token expToken )
{
switch( expToken.Flag ) {
case TokenFlag.Symbol_Unary or TokenFlag.Symbol_Binary:
int cmp = -1;
processPrecedence:
Token tmp = _operators.Peek();
cmp = CompareOperatorPrecedence( expToken, tmp );
if( cmp <= 0 ) {
ConvertOneOperator();
goto processPrecedence;
}
CurrentOperands.Push( expToken );
break;
case TokenFlag.Number or TokenFlag.String or TokenFlag.Member:
CurrentOperands.Push( expToken );
break;
case TokenFlag.Separator_Single: //a , ; found
//if operator stack is not empty, convert all operators to node until meet a separator
Token t;
ExpNode n = _operandsNode.Peek();
int count = 0;
processSection:
t = _operators.Peek();
bool isEnd = expToken.Value switch
{
"," => ",[(".IndexOf( t.Value[ 0 ] ) != -1,
";" => ";{".IndexOf( t.Value[ 0 ] ) != -1,
_ => false
};
if( isEnd ) {
if( count == 0 ) {
ExpNode newNode = ExpNode.NonOperation(
string.Empty );
newNode.AppendNode( n );
} else {
ExpNode newNode = _operandsNode.Pop();
newNode.AppendNode( n );
CurrentOperands.Push( newNode );
}
} else {
count++;
ConvertOneOperator();
goto processSection;
}
break;
case TokenFlag.Separator_Left: //a ( [ { found
_operators.Push( expToken );
break;
case TokenFlag.Separator_Right: //a } ] ) found
break;
case TokenFlag.Index_Left: // a [ found
break;
case TokenFlag.Index_Right: // a ] found
break;
default:
break;
}
}
public ExpNode GetNextOperandCache()
{
if( CurrentOperands.Pop( out Token t, out ExpNode? n ) ) {
return n;
} else {
//TODO convert token to a node
}
}
/// <summary>
/// WARNING: This method cannot process INDEXOF, FUNCTION CALLING, LOOP and any ENDING
/// SYMBOLS.
/// </summary>
private void ConvertOneOperator()
{
Token @operator = _operators.Pop();
switch( @operator.Flag ) {
case TokenFlag.Symbol_Unary:
TryGenerateUnaryNode( @operator, out ExpNode? node );
CurrentOperands.Push( node );
break;
case TokenFlag.Symbol_Binary:
TryGenerateBinaryNode( @operator, out node );
CurrentOperands.Push( node );
break;
default:
break;
}
}
private void DecreaseOperandsStackDepth()
{
_operands.Pop();
}
private void IncreaseOperandsStackDepth()
{
_operands.Push( new TokenNodeStack<ExpNode, IExpElementSource>() );
}
}
}
@@ -0,0 +1,74 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="FunctionCallingGenerator.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 static StgSharp.Script.Express.ExpCompile;
namespace StgSharp.Script.Express
{
public partial class ExpNodeGenerator
{
private bool _isCallingFunction = false;
private Stack<int> _callDepth = new Stack<int>();
private void EnterFunctionCalling( Token funcNameToken )
{
_isCallingFunction = true;
_callDepth.Push( _operandsToken.Count );
}
private void ExitFunctionCalling()
{
_callDepth.Pop();
if( _callDepth.Count == 0 ) {
_isCallingFunction = false;
}
}
//TODO cannot process occasion of void input or null at first
private void MergeFunctionCallingParameter()
{
if( _callDepth.Peek() == _operandsToken.Count ) {
_operandsNode.Peek()
.PrependNode(
ExpNode.NonOperation( PoolString( "FuncParam" ) ) );
} else {
//TODO compile the param expression
}
}
}
}
@@ -0,0 +1,94 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="GenerateOperatorToken.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 ExpNodeGenerator
{
public int CompareOperatorPrecedence( Token left, Token right )
{
ExpCompile.TryGetOperatorPrecedence(
left.Value, out int leftPrecedence );
ExpCompile.TryGetOperatorPrecedence(
right.Value, out int rightPrecedence );
return leftPrecedence - rightPrecedence;
}
public bool TryGenerateBinaryNode( Token t, out ExpNode node )
{
ExpNode left = GetNextOperandCache();
ExpNode right = GetNextOperandCache();
switch( t.Value ) {
case ExpCompile.KeyWord.ADD:
node = ExpBinaryOperatorNode.Add( left, right );
return true;
case ExpCompile.KeyWord.SUB:
node = ExpBinaryOperatorNode.Sub( left, right );
return true;
case ExpCompile.KeyWord.MUL:
node = ExpBinaryOperatorNode.Mul( left, right );
return true;
case ExpCompile.KeyWord.DIV:
node = ExpBinaryOperatorNode.Div( left, right );
return true;
default:
node = ExpNode.Empty;
return false;
}
}
public bool TryGenerateUnaryNode( Token t, out ExpNode node )
{
ExpNode operand = GetNextOperandCache();
switch( t.Value ) {
case ExpCompile.KeyWord.UnaryPlus:
node = ExpUnaryOperatorNode.UnaryPlus( operand );
return true;
case ExpCompile.KeyWord.UnaryMinus:
node = ExpUnaryOperatorNode.UnaryMinus( operand );
return true;
case ExpCompile.KeyWord.NOT:
node = ExpUnaryOperatorNode.UnaryNot( operand );
return true;
default:
node = ExpNode.Empty;
return false;
}
}
}
}
@@ -0,0 +1,85 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="GenerateUnaryToken.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 ExpNodeGenerator
{
public bool TryGenerateBinaryNode( Token t, out ExpNode node )
{
ExpNode left = GetNextOperandCache();
ExpNode right = GetNextOperandCache();
switch( t.Value ) {
case ExpCompile.KeyWord.ADD:
node = ExpBinaryOperatorNode.Add( left, right );
return true;
case ExpCompile.KeyWord.SUB:
node = ExpBinaryOperatorNode.Sub( left, right );
return true;
case ExpCompile.KeyWord.MUL:
node = ExpBinaryOperatorNode.Mul( left, right );
return true;
case ExpCompile.KeyWord.DIV:
node = ExpBinaryOperatorNode.Div( left, right );
return true;
default:
node = ExpNode.Empty;
return false;
}
}
public bool TryGenerateUnaryNode( Token t, out ExpNode node )
{
ExpNode operand = GetNextOperandCache();
switch( t.Value ) {
case ExpCompile.KeyWord.UnaryPlus:
node = ExpUnaryOperatorNode.UnaryPlus( operand );
return true;
case ExpCompile.KeyWord.UnaryMinus:
node = ExpUnaryOperatorNode.UnaryMinus( operand );
return true;
case ExpCompile.KeyWord.NOT:
node = ExpUnaryOperatorNode.UnaryNot( operand );
return true;
default:
node = ExpNode.Empty;
return false;
}
}
}
}
@@ -0,0 +1,67 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="LeftSperatorProcess.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.Frozen;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Script.Express
{
public partial class ExpNodeGenerator
{
private int _lbToken = 0; // [ count
private int _lcbCount = 0; // { count
private int _lpCount = 0; // ( count
private void ProcessLeftSeparator( Token t )
{
switch( t.Value ) {
case "[":
_lbToken++;
break;
case "{":
_lcbCount++;
break;
case "(":
_lpCount++;
break;
default:
break;
}
}
}
}
@@ -0,0 +1,97 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpNodeFlag.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
{
[Flags]
public enum ExpNodeFlag : long
{
//string as name of non-builtin variables
None = 0,
Name_Element = 1,
Name_Param = 2,
Name_Block = 4,
Name_Keyword = 8,
Name_Operator = 16,
Name_Any = Name_Block | Name_Element | Name_Keyword | Name_Param | Name_Operator,
//any type of collections, also has NAME flag
Collection_Set = 32,
Collection_Bag = 64,
Collection_Array = 128,
Collection_List = 256,
Collection_Any = Collection_Set | Collection_Bag | Collection_Array | Collection_List,
//the variable is type of element, both builtin and non-builtin has this flag
Element_Const = 512,
Element_Entity = 1024,
Element_Type = 2048,
Element_Rule = 4096,
Element_Function = 8192,
Element_Any = Element_Entity | Element_Const | Element_Function | Element_Rule | Element_Type,
//variable is one of these builtin type
BuiltinType_Int = 16384,
BuiltinType_Float = 32768,
BuiltinType_String = 65536,
BuiltinType_Boolean = 0x2000,
BuiltinType_Binary = 0x4000,
BuiltinType_Logic = 0x8000,
BuiltinType_Number = BuiltinType_Float | BuiltinType_Int,
BuiltinType_Any = BuiltinType_Int | BuiltinType_Float | BuiltinType_String | BuiltinType_Boolean | BuiltinType_Binary | BuiltinType_Logic,
//the token is root of a branch
Branch_If = 0x1_000,
Branch_Switch = 0x2_0000,
Branch_Repeat = 0x4_0000,
Branch_Any = Branch_If | Branch_Repeat | Branch_Switch,
//the token is one of separators
Separator_Inline = 0x8_0000, //, or sth else
Separator_Line = 0x10_0000, //; or eth else
Separator_Block = 0x20_0000, //{}or sth else
Separator_Range = 0x40_0000, //()or sth else
Separator_Any = Separator_Inline | Separator_Line | Separator_Block | Separator_Range,
//the token is a kind of operator
Operator_Unary = 0x40_0000,
Operator_Binary = 0x80_0000,
Operator_SuperType = 0x100_0000,
Operator_Any = Operator_Unary | Operator_Binary | Operator_SuperType,
}
}
@@ -0,0 +1,78 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ExpNodeNextEnumerator.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;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Script.Express
{
public class ExpNodeNextEnumerator : IEnumerator<ExpNode>
{
private ExpNode _begin;
private ExpNode _current;
public ExpNodeNextEnumerator( ExpNode token )
{
_begin = token;
_current = token;
}
void IDisposable.Dispose()
{
return;
}
bool IEnumerator.MoveNext()
{
ExpNode next = _current.Next;
if( ReferenceEquals( next, _begin ) || next == null ) {
return false;
}
_current = next;
return true;
}
void IEnumerator.Reset()
{
_current = _begin;
}
object IEnumerator.Current => throw new NotImplementedException();
ExpNode IEnumerator<ExpNode>.Current => throw new NotImplementedException(
);
}
}
+98
View File
@@ -0,0 +1,98 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="IASTNode.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.Collections;
using StgSharp.Script.Express;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace StgSharp.Script
{
public interface IASTNode<TNode, TType> where TNode: IASTNode<TNode, TType>
where TType: ITypeSource<TType>
{
long NodeFlag
{
get;
}
string Name
{
get;
}
string CodeConvertTemplate
{
get;
}
TNode Previous
{
get;
set;
}
TNode Next
{
get;
set;
}
TNode Left
{
get;
}
TNode Right
{
get;
}
static abstract TNode Empty
{
get;
}
TType EqualityTypeConvert
{
get;
}
void AppendNode( TNode nextToken );
void PrependNode( TNode previusNode );
}
}
+64
View File
@@ -0,0 +1,64 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="IScriptSourceProvider.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.Text;
namespace StgSharp.Script
{
public interface IScriptSourceProvider
{
bool IsEmpty
{
get;
}
int Location
{
get;
}
void EndWriting();
string ReadLine();
string ReadLine( out int position );
/// <summary>
/// Return part of current provider.
/// </summary>
/// <param name="count"> Count of lines to be sliced </param>
/// <returns></returns>
public IScriptSourceProvider Slice( int location, int count );
}
}
+46
View File
@@ -0,0 +1,46 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ITypeSource.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
{
public interface ITypeSource<in TConvert>
where TConvert: ITypeSource<TConvert>
{
bool IsConvertable( TConvert targetType );
}
}
+159
View File
@@ -0,0 +1,159 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="ScriptSourceTransmitter.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;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace StgSharp.Script
{
/// <summary>
/// Transmit a continuous part of script code to interpreter or compiler. This transmitter is
/// designed for single-thread-write and single-thread read. Any multi thread operation will
/// cause undefined behaviour.
/// </summary>
public class ScriptSourceTransmitter : IScriptSourceProvider
{
private static ScriptSourceTransmitter _empty = new ScriptSourceTransmitter(
string.Empty, 0, 0 )
{
_cache = [],
_buffer = []
};
private string[] _buffer;
private bool _isWriting = true;
private int _begin, _index;
private List<string> _cache;
private readonly string _completeMark;
internal ScriptSourceTransmitter( string[] buffer, int start )
{
_buffer = buffer;
_begin = start;
_isWriting = false;
}
public ScriptSourceTransmitter( string endMark, int start )
{
_cache = new List<string>();
_completeMark = endMark;
_begin = start;
_index = 0;
}
public ScriptSourceTransmitter(
string endMark,
int start,
int capacity )
{
_cache = new List<string>( capacity );
_completeMark = endMark;
_begin = start;
_index = 0;
}
public bool IsEmpty => _isWriting ?
( _cache.Count == 0 ) : ( _buffer.Length == 0 ) || ( _index >=
_buffer.Length );
public bool IsFrozen => !_isWriting;
public int Location => _begin + _index;
public static ScriptSourceTransmitter Empty => _empty;
public void EndWriting()
{
if( !_isWriting ) {
return;
}
_isWriting = false;
_buffer = _cache.ToArray();
_cache = null!;
}
public string ReadLine()
{
if( _isWriting ) {
throw new InvalidOperationException(
"Cannot read before all writing operation." );
}
if( _index >= _buffer.Length ) {
return string.Empty;
}
string str = _buffer[ _index ];
_index++;
return str;
}
public string ReadLine( out int position )
{
if( _isWriting ) {
throw new InvalidOperationException(
"Cannot read before all writing operation." );
}
if( _index >= _buffer.Length ) {
position = -1;
return string.Empty;
}
position = _begin + _index;
string str = _buffer[ _index ];
_index++;
return str;
}
public IScriptSourceProvider Slice( int location, int count )
{
ArgumentOutOfRangeException.ThrowIfLessThan( location, _begin );
ArgumentOutOfRangeException.ThrowIfGreaterThan(
location + count, _begin + _buffer.Length );
return new ScriptSourceTransmitter(
_buffer.AsSpan().Slice( location, count ).ToArray(), location );
}
public void WriteLine( string line )
{
if( !_isWriting ) {
return;
}
if( string.Equals( _completeMark, line ) ) {
EndWriting();
return;
}
_cache.Add( line );
}
}
}
+1 -1
View File
@@ -5,7 +5,7 @@
<Nullable>enable</Nullable>
<LangVersion>preview</LangVersion>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<Platforms>x64;ARM64</Platforms>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<ItemGroup>
+80
View File
@@ -0,0 +1,80 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="Token.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
{
public readonly struct Token
{
private static Token EmptyToken = new Token();
public readonly int Column;
public readonly int Line;
public readonly string Value;
public readonly TokenFlag Flag;
public Token(
string chars,
int lineNumber,
int columnNumber,
TokenFlag flag )
{
Value = chars;
Line = lineNumber;
Column = columnNumber;
Flag = flag;
}
public static Token Empty => EmptyToken;
}
public enum TokenFlag : int
{
Symbol_Unary = 1,
Symbol_Binary = 2,
Number = 3,
String = 4,
Member = 5,
Separator_Single = 6,
Separator_Left = 7,
Separator_Right = 8,
Index_Left = 9,
Index_Right = 10,
}
}
+99
View File
@@ -0,0 +1,99 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="TokenNodeStack.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.Data;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Script
{
public class TokenNodeStack<TNode, TType>
where TNode: IASTNode<TNode, TType>
where TType: ITypeSource<TType>
{
private Stack<bool> _isNode;
private Stack<TNode> _nodes;
private Stack<Token> _tokens;
public TokenNodeStack()
{
_nodes = new Stack<TNode>( 4 );
_tokens = new Stack<Token>( 4 );
_isNode = new Stack<bool>( 8 );
}
public int Count => _isNode.Count;
public bool Peek( out Token t, TNode n )
{
if( _isNode.Peek() ) {
n = _nodes.Peek();
t = Token.Empty;
return true;
} else {
t = _tokens.Peek();
n = TNode.Empty;
return false;
}
}
public bool Pop( out Token t, out TNode n )
{
if( _isNode.Pop() ) {
n = _nodes.Pop();
t = Token.Empty;
return true;
} else {
t = _tokens.Pop();
n = TNode.Empty;
return false;
}
}
public void Push( TNode node )
{
_nodes.Push( node );
_isNode.Push( true );
}
public void Push( Token token )
{
_tokens.Push( token );
_isNode.Push( false );
}
}
}