Daily update on 20250324-100332 by Nitload Youmu. Additional Message : Single line syntax analyzer ok, gonging on unit test of multi line, func call. Then building branch, loop, area syntax analyzer. Some of descriptors not supported.
Signed-off-by: Nitload <YoumuLiu_NSI@whv0t.onmicrosoft.com>
This commit is contained in:
@@ -41,8 +41,7 @@ namespace StgSharp.Script.Express
|
||||
internal partial class ExpSchema_Builtin : ExpSchema
|
||||
{
|
||||
|
||||
private static readonly ExpSchema_Builtin _onlyInstance = new ExpSchema_Builtin(
|
||||
);
|
||||
private static readonly ExpSchema_Builtin _onlyInstance = new ExpSchema_Builtin();
|
||||
|
||||
private ExpSchema_Builtin()
|
||||
: base()
|
||||
@@ -60,9 +59,7 @@ namespace StgSharp.Script.Express
|
||||
return;
|
||||
}
|
||||
|
||||
public override bool TryGetConst(
|
||||
string name,
|
||||
out ExpElementInstanceBase c )
|
||||
public override bool TryGetConst( string name, out ExpElementInstanceBase c )
|
||||
{
|
||||
return ConstDict.TryGetValue( name, out c );
|
||||
}
|
||||
@@ -73,9 +70,7 @@ namespace StgSharp.Script.Express
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool TryGetFunction(
|
||||
string name,
|
||||
out ExpFunctionSource f )
|
||||
public override bool TryGetFunction( string name, out ExpFunctionSource f )
|
||||
{
|
||||
return FunctionDict.TryGetValue( name, out f! );
|
||||
}
|
||||
@@ -86,9 +81,7 @@ namespace StgSharp.Script.Express
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool TryGetSchemaInclude(
|
||||
string name,
|
||||
out ExpSchema include )
|
||||
public override bool TryGetSchemaInclude( string name, out ExpSchema include )
|
||||
{
|
||||
include = null!;
|
||||
return false;
|
||||
@@ -103,37 +96,33 @@ namespace StgSharp.Script.Express
|
||||
{
|
||||
IEnumerable<KeyValuePair<string, ExpTypeSource>> builtinTypeSource = [
|
||||
new KeyValuePair<string, ExpTypeSource>(
|
||||
PoolString( KeyWord.Integer ),
|
||||
new ExpBuiltinType( KeyWord.Integer, typeof( int ) ) ),
|
||||
PoolString( Keyword.Integer ),
|
||||
new ExpBuiltinType( Keyword.Integer, typeof( int ) ) ),
|
||||
new KeyValuePair<string, ExpTypeSource>(
|
||||
PoolString( KeyWord.Real ),
|
||||
new ExpBuiltinType( KeyWord.Real, typeof( float ) ) ),
|
||||
PoolString( Keyword.Real ), new ExpBuiltinType( Keyword.Real, typeof( float ) ) ),
|
||||
new KeyValuePair<string, ExpTypeSource>(
|
||||
PoolString( KeyWord.Boolean ),
|
||||
new ExpBuiltinType( KeyWord.Boolean, typeof( bool ) ) ),
|
||||
PoolString( Keyword.Boolean ),
|
||||
new ExpBuiltinType( Keyword.Boolean, typeof( bool ) ) ),
|
||||
new KeyValuePair<string, ExpTypeSource>(
|
||||
PoolString( KeyWord.Logical ),
|
||||
new ExpBuiltinType( KeyWord.Logical, typeof( ExpLogic ) ) ),
|
||||
PoolString( Keyword.Logical ),
|
||||
new ExpBuiltinType( Keyword.Logical, typeof( ExpLogic ) ) ),
|
||||
new KeyValuePair<string, ExpTypeSource>(
|
||||
PoolString( KeyWord.String ),
|
||||
new ExpBuiltinType( KeyWord.String, typeof( string ) ) ),
|
||||
PoolString( Keyword.String ),
|
||||
new ExpBuiltinType( Keyword.String, typeof( string ) ) ),
|
||||
new KeyValuePair<string, ExpTypeSource>(
|
||||
PoolString( KeyWord.Binary ),
|
||||
new ExpBuiltinType( KeyWord.Binary, typeof( BitArray ) ) ),
|
||||
PoolString( Keyword.Binary ),
|
||||
new ExpBuiltinType( Keyword.Binary, typeof( BitArray ) ) ),
|
||||
|
||||
];
|
||||
TypeDict = new Dictionary<string, ExpTypeSource>(
|
||||
builtinTypeSource, Multiplexer ).ToFrozenDictionary();
|
||||
TypeDict = new Dictionary<string, ExpTypeSource>( builtinTypeSource,
|
||||
Multiplexer ).ToFrozenDictionary();
|
||||
|
||||
|
||||
ConstDict = new Dictionary<string, ExpElementInstanceBase>(
|
||||
Multiplexer ) {
|
||||
ConstDict = new Dictionary<string, ExpElementInstanceBase>( Multiplexer ) {
|
||||
{ PoolString( "PI" ), new ExpRealNumberNode(
|
||||
new Token( PoolString( "PI" ), -1, -1, TokenFlag.Number ),
|
||||
MathF.PI ) },
|
||||
new Token( PoolString( "PI" ), -1, -1, TokenFlag.Number ), MathF.PI ) },
|
||||
{ PoolString( "E" ), new ExpRealNumberNode(
|
||||
new Token( PoolString( "E" ), -1, -1, TokenFlag.Number ),
|
||||
MathF.E ) },
|
||||
new Token( PoolString( "E" ), -1, -1, TokenFlag.Number ), MathF.E ) },
|
||||
}.ToFrozenDictionary();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="ExpressCompile.cs"
|
||||
// file="ExpCompile.cs"
|
||||
// Project: StgSharp
|
||||
// AuthorGroup: Nitload Space
|
||||
// Copyright (c) Nitload Space. All rights reserved.
|
||||
@@ -88,32 +88,28 @@ namespace StgSharp.Script.Express
|
||||
InitPrecedence();
|
||||
|
||||
_operatorsWithLetter = [
|
||||
KeyWord.Add,
|
||||
KeyWord.Sub,
|
||||
KeyWord.Mul,
|
||||
KeyWord.Div,
|
||||
KeyWord.And,
|
||||
KeyWord.Or,
|
||||
KeyWord.Xor,
|
||||
KeyWord.AndOr,
|
||||
KeyWord.Not,
|
||||
Keyword.Add,
|
||||
Keyword.Sub,
|
||||
Keyword.Mul,
|
||||
Keyword.Div,
|
||||
Keyword.And,
|
||||
Keyword.Or,
|
||||
Keyword.Xor,
|
||||
Keyword.AndOr,
|
||||
Keyword.Not,
|
||||
];
|
||||
|
||||
ExpSchema_Builtin.Only
|
||||
.TryGetType(
|
||||
PoolString( KeyWord.Integer ),
|
||||
out ExpTypeSource? _expInt );
|
||||
.TryGetType(
|
||||
PoolString( Keyword.Integer ), out ExpTypeSource? _expInt );
|
||||
ExpInt = _expInt;
|
||||
|
||||
ExpSchema_Builtin.Only
|
||||
.TryGetType(
|
||||
PoolString( KeyWord.Real ),
|
||||
out ExpTypeSource? _expReal );
|
||||
.TryGetType( PoolString( Keyword.Real ), out ExpTypeSource? _expReal );
|
||||
ExpReal = _expReal;
|
||||
ExpSchema_Builtin.Only
|
||||
.TryGetType(
|
||||
PoolString( KeyWord.Boolean ),
|
||||
out ExpTypeSource? _expBool );
|
||||
.TryGetType(
|
||||
PoolString( Keyword.Boolean ), out ExpTypeSource? _expBool );
|
||||
ExpBool = _expBool;
|
||||
|
||||
_emptyCache = new StringPool();
|
||||
|
||||
@@ -40,20 +40,16 @@ namespace StgSharp.Script.Express
|
||||
public static partial class ExpressCompile
|
||||
{
|
||||
|
||||
public static bool TryGetOperatorPrecedence(
|
||||
string operatorName,
|
||||
out int precedence )
|
||||
public static bool TryGetOperatorPrecedence( string operatorName, out int precedence )
|
||||
{
|
||||
return _operatorPrecedence.TryGetValue(
|
||||
operatorName, out precedence );
|
||||
return _operatorPrecedence.TryGetValue( operatorName, out precedence );
|
||||
}
|
||||
|
||||
public static bool TryGetSuperTypeOperatorPrecedence(
|
||||
string operatorName,
|
||||
out int precedence )
|
||||
string operatorName,
|
||||
out int precedence )
|
||||
{
|
||||
return _superTypeOperatorPrecedent.TryGetValue(
|
||||
operatorName, out precedence );
|
||||
return _superTypeOperatorPrecedent.TryGetValue( operatorName, out precedence );
|
||||
}
|
||||
|
||||
private static void InitPrecedence()
|
||||
@@ -86,16 +82,18 @@ namespace StgSharp.Script.Express
|
||||
new KeyValuePair<string, int>( PoolString( ":<>:" ), 6 ),
|
||||
new KeyValuePair<string, int>( PoolString( "IN" ), 6 ),
|
||||
new KeyValuePair<string, int>( PoolString( "LIKE" ), 6 ),
|
||||
new KeyValuePair<string, int>( PoolString( Keyword.Assignment ), 7 )
|
||||
];
|
||||
_operatorPrecedence = new Dictionary<string, int>(
|
||||
source, _multiplexer ).ToFrozenDictionary();
|
||||
_operatorPrecedence = new Dictionary<string, int>( source,
|
||||
_multiplexer ).ToFrozenDictionary();
|
||||
source = [
|
||||
new KeyValuePair<string, int>( "ONEOF", 1 ),
|
||||
new KeyValuePair<string, int>( "AND", 2 ),
|
||||
new KeyValuePair<string, int>( "ANDOR", 3 ),
|
||||
];
|
||||
_superTypeOperatorPrecedent = new Dictionary<string, int>(
|
||||
source, _multiplexer ).ToFrozenDictionary();
|
||||
_superTypeOperatorPrecedent = new Dictionary<string, int>( source,
|
||||
_multiplexer ).ToFrozenDictionary(
|
||||
);
|
||||
}
|
||||
|
||||
#pragma warning disable CS8618
|
||||
|
||||
@@ -46,12 +46,11 @@ namespace StgSharp.Script.Express
|
||||
{
|
||||
_keywordSet = new();
|
||||
|
||||
FieldInfo[] fields = typeof( KeyWord ).GetFields(
|
||||
BindingFlags.Public );
|
||||
FieldInfo[] fields = typeof( Keyword ).GetFields( BindingFlags.Public );
|
||||
ParallelLoopResult result = Parallel.ForEach(
|
||||
fields, static( field ) => {
|
||||
if( field.FieldType == typeof( string ) && field.GetValue(
|
||||
null ) is string str ) {
|
||||
if( field.FieldType == typeof( string ) && field.GetValue( null ) is string str )
|
||||
{
|
||||
_compileStringCache.GetOrAdd( str );
|
||||
_keywordSet.Add( str );
|
||||
}
|
||||
@@ -59,7 +58,7 @@ namespace StgSharp.Script.Express
|
||||
while( !result.IsCompleted ) { }
|
||||
}
|
||||
|
||||
public static class KeyWord
|
||||
public static class Keyword
|
||||
{
|
||||
|
||||
public static HashSet<string> ScopeBlock = new HashSet<string> {
|
||||
@@ -74,24 +73,15 @@ namespace StgSharp.Script.Express
|
||||
CommentStart, CommentEnd, ColonEqualColon, ColonNotEqualColon
|
||||
];
|
||||
|
||||
public static HashSet<string> DataTypes
|
||||
{
|
||||
get;
|
||||
} = [
|
||||
public static HashSet<string> DataTypes { get; } = [
|
||||
Array, Bag, Binary, Boolean, Enumeration, Integer, List, Logical, Number, Of, Real, Set, String
|
||||
];
|
||||
|
||||
public static HashSet<string> InternalProcess
|
||||
{
|
||||
get;
|
||||
} = [
|
||||
public static HashSet<string> InternalProcess { get; } = [
|
||||
Insert, Remove
|
||||
];
|
||||
|
||||
public static HashSet<string> BuiltinFunctions
|
||||
{
|
||||
get;
|
||||
} = [
|
||||
public static HashSet<string> BuiltinFunctions { get; } = [
|
||||
Abs, Acos, Asin, Atan, BLength, Cos, Exists, Exp,
|
||||
Format, HiBound, HiIndex, Length, LoBound, Log,
|
||||
Log2, Log10, LoIndex, Nvl, Odd, Rolesof, Sin,
|
||||
@@ -99,62 +89,38 @@ namespace StgSharp.Script.Express
|
||||
ValueIn, ValueUnique
|
||||
];
|
||||
|
||||
public static HashSet<string> Literals
|
||||
{
|
||||
get;
|
||||
} = [
|
||||
public static HashSet<string> Literals { get; } = [
|
||||
QuestionMark, Self, Const, E, Pi, False, True, Unknown
|
||||
];
|
||||
|
||||
public static HashSet<string> Operators
|
||||
{
|
||||
get;
|
||||
} = [
|
||||
public static HashSet<string> Operators { get; } = [
|
||||
And, AndOr, Div, In, Like, Mod, Not, Or, Xor,
|
||||
Add, Sub, Mul, Slash, Equal, NotEqual,
|
||||
LessThan, GreaterThan, LessThanOrEqual, GreaterThanOrEqual
|
||||
];
|
||||
|
||||
public static HashSet<string> Aliasing
|
||||
{
|
||||
get;
|
||||
} = [
|
||||
public static HashSet<string> Aliasing { get; } = [
|
||||
Alias, Renamed
|
||||
];
|
||||
|
||||
public static HashSet<string> ModifiersAttributes
|
||||
{
|
||||
get;
|
||||
} = [
|
||||
public static HashSet<string> ModifiersAttributes { get; } = [
|
||||
Abstract, Aggregate, As, BasedOn, By, Escape, Fixed, From, Use, With
|
||||
];
|
||||
|
||||
public static HashSet<string> QueryReference
|
||||
{
|
||||
get;
|
||||
} = [
|
||||
public static HashSet<string> QueryReference { get; } = [
|
||||
Query, Reference, Select
|
||||
];
|
||||
|
||||
public static HashSet<string> ConstraintsInheritance
|
||||
{
|
||||
get;
|
||||
} = [
|
||||
public static HashSet<string> ConstraintsInheritance { get; } = [
|
||||
Oneof, Optional, Subtype, SubtypeConstraint, Supertype, TotalOver, Unique, Where
|
||||
];
|
||||
|
||||
public static HashSet<string> Declarations
|
||||
{
|
||||
get;
|
||||
} = [
|
||||
public static HashSet<string> Declarations { get; } = [
|
||||
Constant, Derive, Entity, Extensible, Fixed, Function, Generic,
|
||||
GenericEntity, Inverse, Local, Procedure, Rule, Schema, Type, Var
|
||||
];
|
||||
|
||||
public static HashSet<string> FlowControl
|
||||
{
|
||||
get;
|
||||
} = [
|
||||
public static HashSet<string> FlowControl { get; } = [
|
||||
Begin, Case, Else, End, For, If, Otherwise, Repeat, Return, Skip, Then, To, Until, While
|
||||
];
|
||||
|
||||
|
||||
@@ -45,8 +45,7 @@ namespace StgSharp.Script.Express
|
||||
private Dictionary<string, ExpElementInstanceBase> _constants;
|
||||
private IScriptSourceProvider _sourceProvider;
|
||||
|
||||
public ExpConstantCollectionSource(
|
||||
IScriptSourceProvider sourceProvider )
|
||||
public ExpConstantCollectionSource( IScriptSourceProvider sourceProvider )
|
||||
{
|
||||
_sourceProvider = sourceProvider;
|
||||
_constants = new Dictionary<string, ExpElementInstanceBase>(
|
||||
@@ -59,7 +58,7 @@ namespace StgSharp.Script.Express
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get => ExpressCompile.KeyWord.Constant;
|
||||
get => ExpressCompile.Keyword.Constant;
|
||||
}
|
||||
|
||||
public override void Analyse()
|
||||
@@ -75,24 +74,21 @@ namespace StgSharp.Script.Express
|
||||
if( _constants.Count == 0 ) {
|
||||
return null!;
|
||||
}
|
||||
if( _constants.TryGetValue( str,
|
||||
out ExpElementInstanceBase? token ) ) {
|
||||
if( _constants.TryGetValue( str, out ExpElementInstanceBase? token ) ) {
|
||||
return token;
|
||||
}
|
||||
return null!;
|
||||
}
|
||||
|
||||
public bool TryGetConstant(
|
||||
string name,
|
||||
out ExpElementInstanceBase instance )
|
||||
public bool TryGetConstant( string name, out ExpElementInstanceBase instance )
|
||||
{
|
||||
return _constants.TryGetValue( name, out instance );
|
||||
}
|
||||
|
||||
public override bool TryGetMember( string name, out ExpNode memberNode )
|
||||
{
|
||||
if( _constants.TryGetValue( name,
|
||||
out ExpElementInstanceBase? node ) ) {
|
||||
if( _constants.TryGetValue( name, out ExpElementInstanceBase? node ) )
|
||||
{
|
||||
memberNode = node;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,12 @@ namespace StgSharp.Script.Express
|
||||
private ExpNode _left;
|
||||
private ExpNode _right;
|
||||
|
||||
private ExpBinaryOperatorNode( Token source ) : base( source ) { }
|
||||
private ExpBinaryOperatorNode( Token source, ExpNode left, ExpNode right )
|
||||
: base( source )
|
||||
{
|
||||
_left = left;
|
||||
_right = right;
|
||||
}
|
||||
|
||||
public override ExpInstantiableElement EqualityTypeConvert => _returnType;
|
||||
|
||||
@@ -54,77 +59,59 @@ namespace StgSharp.Script.Express
|
||||
|
||||
public override ExpNode Right => _right;
|
||||
|
||||
public static ExpBinaryOperatorNode Add(
|
||||
Token source,
|
||||
ExpNode left,
|
||||
ExpNode right )
|
||||
public static ExpBinaryOperatorNode Add( Token source, ExpNode left, ExpNode right )
|
||||
{
|
||||
if( !left.IsNumber && !right.IsNumber ) {
|
||||
throw new ExpInvalidTypeException(
|
||||
"Number", left.EqualityTypeConvert.Name );
|
||||
throw new ExpInvalidTypeException( "Number", left.EqualityTypeConvert.Name );
|
||||
}
|
||||
bool isFloat =
|
||||
( left._nodeFlag | ExpNodeFlag.BuiltinType_Real ) == 0 || ( right._nodeFlag | ExpNodeFlag.BuiltinType_Real ) ==
|
||||
0;
|
||||
return new ExpBinaryOperatorNode( source )
|
||||
return new ExpBinaryOperatorNode( source, left, right )
|
||||
{
|
||||
_returnType = isFloat ?
|
||||
ExpressCompile.ExpReal : ExpressCompile.ExpInt,
|
||||
_returnType = isFloat ? ExpressCompile.ExpReal : ExpressCompile.ExpInt,
|
||||
_nodeFlag = ExpNodeFlag.Operator_Binary | ExpNodeFlag.BuiltinType_Number,
|
||||
CodeConvertTemplate = "{0} + {1}",
|
||||
};
|
||||
}
|
||||
|
||||
public static ExpBinaryOperatorNode Assign(
|
||||
Token source,
|
||||
ExpNode left,
|
||||
ExpNode right )
|
||||
public static ExpBinaryOperatorNode Assign( Token source, ExpNode left, ExpNode right )
|
||||
{
|
||||
if( left.EqualityTypeConvert != right.EqualityTypeConvert ) {
|
||||
throw new ExpInvalidTypeException(
|
||||
left.EqualityTypeConvert.Name,
|
||||
right.EqualityTypeConvert.Name );
|
||||
left.EqualityTypeConvert.Name, right.EqualityTypeConvert.Name );
|
||||
}
|
||||
return new ExpBinaryOperatorNode( source )
|
||||
return new ExpBinaryOperatorNode( source, left, right )
|
||||
{
|
||||
_returnType = ExpInstantiableElement.Void,
|
||||
_nodeFlag = ExpNodeFlag.Operator_Binary | left._nodeFlag,
|
||||
CodeConvertTemplate = "{0} & {1}",
|
||||
CodeConvertTemplate = "{0} = {1}",
|
||||
};
|
||||
}
|
||||
|
||||
public static ExpBinaryOperatorNode Div(
|
||||
Token source,
|
||||
ExpNode left,
|
||||
ExpNode right )
|
||||
public static ExpBinaryOperatorNode Div( Token source, ExpNode left, ExpNode right )
|
||||
{
|
||||
if( !left.IsNumber && !right.IsNumber ) {
|
||||
throw new ExpInvalidTypeException(
|
||||
"Number", left.EqualityTypeConvert.Name );
|
||||
throw new ExpInvalidTypeException( "Number", left.EqualityTypeConvert.Name );
|
||||
}
|
||||
bool isFloat =
|
||||
( left._nodeFlag | ExpNodeFlag.BuiltinType_Real ) == 0 || ( right._nodeFlag | ExpNodeFlag.BuiltinType_Real ) ==
|
||||
0;
|
||||
return new ExpBinaryOperatorNode( source )
|
||||
return new ExpBinaryOperatorNode( source, left, right )
|
||||
{
|
||||
_returnType = isFloat ?
|
||||
ExpressCompile.ExpReal : ExpressCompile.ExpInt,
|
||||
_returnType = isFloat ? ExpressCompile.ExpReal : ExpressCompile.ExpInt,
|
||||
_nodeFlag = ExpNodeFlag.Operator_Binary | ExpNodeFlag.BuiltinType_Number,
|
||||
CodeConvertTemplate = "{0} / {1}",
|
||||
};
|
||||
}
|
||||
|
||||
public static ExpBinaryOperatorNode EqualTo(
|
||||
Token source,
|
||||
ExpNode left,
|
||||
ExpNode right )
|
||||
public static ExpBinaryOperatorNode EqualTo( Token source, ExpNode left, ExpNode right )
|
||||
{
|
||||
if( left.EqualityTypeConvert != right.EqualityTypeConvert ) {
|
||||
throw new ExpInvalidTypeException(
|
||||
left.EqualityTypeConvert.Name,
|
||||
right.EqualityTypeConvert.Name );
|
||||
left.EqualityTypeConvert.Name, right.EqualityTypeConvert.Name );
|
||||
}
|
||||
return new ExpBinaryOperatorNode( source )
|
||||
return new ExpBinaryOperatorNode( source, left, right )
|
||||
{
|
||||
_returnType = ExpressCompile.ExpBool,
|
||||
_nodeFlag = ExpNodeFlag.BuiltinType_Boolean | ExpNodeFlag.Operator_Binary,
|
||||
@@ -132,16 +119,12 @@ namespace StgSharp.Script.Express
|
||||
};
|
||||
}
|
||||
|
||||
public static ExpBinaryOperatorNode GreaterThan(
|
||||
Token source,
|
||||
ExpNode left,
|
||||
ExpNode right )
|
||||
public static ExpBinaryOperatorNode GreaterThan( Token source, ExpNode left, ExpNode right )
|
||||
{
|
||||
if( !left.IsNumber && !right.IsNumber ) {
|
||||
throw new ExpInvalidTypeException(
|
||||
"Number", left.EqualityTypeConvert.Name );
|
||||
throw new ExpInvalidTypeException( "Number", left.EqualityTypeConvert.Name );
|
||||
}
|
||||
return new ExpBinaryOperatorNode( source )
|
||||
return new ExpBinaryOperatorNode( source, left, right )
|
||||
{
|
||||
_returnType = ExpressCompile.ExpBool,
|
||||
_nodeFlag = ExpNodeFlag.BuiltinType_Boolean | ExpNodeFlag.Operator_Binary,
|
||||
@@ -149,16 +132,12 @@ namespace StgSharp.Script.Express
|
||||
};
|
||||
}
|
||||
|
||||
public static ExpBinaryOperatorNode LessThan(
|
||||
Token source,
|
||||
ExpNode left,
|
||||
ExpNode right )
|
||||
public static ExpBinaryOperatorNode LessThan( Token source, ExpNode left, ExpNode right )
|
||||
{
|
||||
if( !left.IsNumber && !right.IsNumber ) {
|
||||
throw new ExpInvalidTypeException(
|
||||
"Number", left.EqualityTypeConvert.Name );
|
||||
throw new ExpInvalidTypeException( "Number", left.EqualityTypeConvert.Name );
|
||||
}
|
||||
return new ExpBinaryOperatorNode( source )
|
||||
return new ExpBinaryOperatorNode( source, left, right )
|
||||
{
|
||||
_returnType = ExpressCompile.ExpBool,
|
||||
_nodeFlag = ExpNodeFlag.BuiltinType_Boolean | ExpNodeFlag.Operator_Binary,
|
||||
@@ -166,38 +145,29 @@ namespace StgSharp.Script.Express
|
||||
};
|
||||
}
|
||||
|
||||
public static ExpBinaryOperatorNode Mul(
|
||||
Token source,
|
||||
ExpNode left,
|
||||
ExpNode right )
|
||||
public static ExpBinaryOperatorNode Mul( Token source, ExpNode left, ExpNode right )
|
||||
{
|
||||
if( !left.IsNumber && !right.IsNumber ) {
|
||||
throw new ExpInvalidTypeException(
|
||||
"Number", left.EqualityTypeConvert.Name );
|
||||
throw new ExpInvalidTypeException( "Number", left.EqualityTypeConvert.Name );
|
||||
}
|
||||
bool isFloat =
|
||||
( left._nodeFlag | ExpNodeFlag.BuiltinType_Real ) == 0 || ( right._nodeFlag | ExpNodeFlag.BuiltinType_Real ) ==
|
||||
0;
|
||||
return new ExpBinaryOperatorNode( source )
|
||||
return new ExpBinaryOperatorNode( source, left, right )
|
||||
{
|
||||
_returnType = isFloat ?
|
||||
ExpressCompile.ExpReal : ExpressCompile.ExpInt,
|
||||
_returnType = isFloat ? ExpressCompile.ExpReal : ExpressCompile.ExpInt,
|
||||
_nodeFlag = ExpNodeFlag.Operator_Binary | ExpNodeFlag.BuiltinType_Number,
|
||||
CodeConvertTemplate = "{0} * {1}",
|
||||
};
|
||||
}
|
||||
|
||||
public static ExpBinaryOperatorNode NotEqualTo(
|
||||
Token source,
|
||||
ExpNode left,
|
||||
ExpNode right )
|
||||
public static ExpBinaryOperatorNode NotEqualTo( Token source, ExpNode left, ExpNode right )
|
||||
{
|
||||
if( left.EqualityTypeConvert != right.EqualityTypeConvert ) {
|
||||
throw new ExpInvalidTypeException(
|
||||
left.EqualityTypeConvert.Name,
|
||||
right.EqualityTypeConvert.Name );
|
||||
left.EqualityTypeConvert.Name, right.EqualityTypeConvert.Name );
|
||||
}
|
||||
return new ExpBinaryOperatorNode( source )
|
||||
return new ExpBinaryOperatorNode( source, left, right )
|
||||
{
|
||||
_returnType = ExpressCompile.ExpBool,
|
||||
_nodeFlag = ExpNodeFlag.BuiltinType_Boolean | ExpNodeFlag.Operator_Binary,
|
||||
@@ -205,16 +175,12 @@ namespace StgSharp.Script.Express
|
||||
};
|
||||
}
|
||||
|
||||
public static ExpBinaryOperatorNode SmallerThan(
|
||||
Token source,
|
||||
ExpNode left,
|
||||
ExpNode right )
|
||||
public static ExpBinaryOperatorNode SmallerThan( Token source, ExpNode left, ExpNode right )
|
||||
{
|
||||
if( !left.IsNumber && !right.IsNumber ) {
|
||||
throw new ExpInvalidTypeException(
|
||||
"Number", left.EqualityTypeConvert.Name );
|
||||
throw new ExpInvalidTypeException( "Number", left.EqualityTypeConvert.Name );
|
||||
}
|
||||
return new ExpBinaryOperatorNode( source )
|
||||
return new ExpBinaryOperatorNode( source, left, right )
|
||||
{
|
||||
_returnType = ExpressCompile.ExpBool,
|
||||
_nodeFlag = ExpNodeFlag.BuiltinType_Boolean | ExpNodeFlag.Operator_Binary,
|
||||
@@ -222,22 +188,17 @@ namespace StgSharp.Script.Express
|
||||
};
|
||||
}
|
||||
|
||||
public static ExpBinaryOperatorNode Sub(
|
||||
Token source,
|
||||
ExpNode left,
|
||||
ExpNode right )
|
||||
public static ExpBinaryOperatorNode Sub( Token source, ExpNode left, ExpNode right )
|
||||
{
|
||||
if( !left.IsNumber && !right.IsNumber ) {
|
||||
throw new ExpInvalidTypeException(
|
||||
"Number", left.EqualityTypeConvert.Name );
|
||||
throw new ExpInvalidTypeException( "Number", left.EqualityTypeConvert.Name );
|
||||
}
|
||||
bool isFloat =
|
||||
( left._nodeFlag | ExpNodeFlag.BuiltinType_Real ) == 0 || ( right._nodeFlag | ExpNodeFlag.BuiltinType_Real ) ==
|
||||
0;
|
||||
return new ExpBinaryOperatorNode( source )
|
||||
return new ExpBinaryOperatorNode( source, left, right )
|
||||
{
|
||||
_returnType = isFloat ?
|
||||
ExpressCompile.ExpReal : ExpressCompile.ExpInt,
|
||||
_returnType = isFloat ? ExpressCompile.ExpReal : ExpressCompile.ExpInt,
|
||||
_nodeFlag = ExpNodeFlag.Operator_Binary | ExpNodeFlag.BuiltinType_Number,
|
||||
CodeConvertTemplate = "{0} - {1}",
|
||||
};
|
||||
|
||||
@@ -55,9 +55,7 @@ namespace StgSharp.Script.Express
|
||||
get
|
||||
{
|
||||
ExpSchema.BuiltinSchema
|
||||
.TryGetType(
|
||||
ExpressCompile.KeyWord.String,
|
||||
out ExpTypeSource? strType );
|
||||
.TryGetType( ExpressCompile.Keyword.String, out ExpTypeSource? strType );
|
||||
return strType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,22 +42,19 @@ namespace StgSharp.Script.Express
|
||||
|
||||
private ExpElementInstanceBase _instance;
|
||||
|
||||
internal ExpInstanceReferenceNode(
|
||||
Token source,
|
||||
ExpElementInstanceBase instance )
|
||||
internal ExpInstanceReferenceNode( Token source, ExpElementInstanceBase instance )
|
||||
: base( source )
|
||||
{
|
||||
_instance = instance;
|
||||
_nodeFlag = ( _instance._nodeFlag | ( ExpNodeFlag.Name_Any | ExpNodeFlag.Collection_Any ) );
|
||||
}
|
||||
|
||||
internal ExpInstanceReferenceNode(
|
||||
Token source,
|
||||
ExpInstanceReferenceNode reference )
|
||||
internal ExpInstanceReferenceNode( Token source, ExpInstanceReferenceNode reference )
|
||||
: base( source )
|
||||
{
|
||||
_instance = reference._instance;
|
||||
_nodeFlag = ( _instance._nodeFlag | ( ExpNodeFlag.Name_Any | ExpNodeFlag.Collection_Any ) );
|
||||
CodeConvertTemplate = source.Value;
|
||||
}
|
||||
|
||||
public override ExpNode Left => Empty;
|
||||
@@ -68,9 +65,14 @@ namespace StgSharp.Script.Express
|
||||
|
||||
[MethodImpl( MethodImplOptions.AggressiveInlining )]
|
||||
public static ExpInstanceReferenceNode Create(
|
||||
Token source,
|
||||
ExpElementInstanceBase instance )
|
||||
Token source,
|
||||
ExpElementInstanceBase instance )
|
||||
{
|
||||
/*
|
||||
if( instance.CodeConvertTemplate != source.Value ) {
|
||||
throw new ExpCompileException( source, "Token point at a wrong instance" );
|
||||
}
|
||||
/**/
|
||||
return new ExpInstanceReferenceNode( source, instance );
|
||||
}
|
||||
|
||||
|
||||
@@ -50,14 +50,14 @@ namespace StgSharp.Script.Express
|
||||
}
|
||||
|
||||
public override IExpElementSource EqualityTypeConvert => ExpSchema.BuiltinSchema
|
||||
.TryGetType(
|
||||
ExpressCompile.KeyWord.Integer,
|
||||
out ExpTypeSource? type ) ?
|
||||
.TryGetType(
|
||||
ExpressCompile.Keyword.Integer,
|
||||
out ExpTypeSource? type ) ?
|
||||
type : throw new ExpCompileNotInitializedException();
|
||||
|
||||
public int Value => _value;
|
||||
|
||||
public override string TypeName => ExpressCompile.KeyWord.Integer;
|
||||
public override string TypeName => ExpressCompile.Keyword.Integer;
|
||||
|
||||
}
|
||||
|
||||
@@ -74,9 +74,9 @@ namespace StgSharp.Script.Express
|
||||
}
|
||||
|
||||
public override IExpElementSource EqualityTypeConvert => ExpSchema.BuiltinSchema
|
||||
.TryGetType(
|
||||
ExpressCompile.KeyWord.String,
|
||||
out ExpTypeSource? type ) ?
|
||||
.TryGetType(
|
||||
ExpressCompile.Keyword.String,
|
||||
out ExpTypeSource? type ) ?
|
||||
type : throw new ExpCompileNotInitializedException();
|
||||
|
||||
public override string TypeName => EqualityTypeConvert.Name;
|
||||
@@ -100,9 +100,9 @@ namespace StgSharp.Script.Express
|
||||
public bool Value => _value;
|
||||
|
||||
public override IExpElementSource EqualityTypeConvert => ExpSchema.BuiltinSchema
|
||||
.TryGetType(
|
||||
ExpressCompile.KeyWord.Boolean,
|
||||
out ExpTypeSource? type ) ?
|
||||
.TryGetType(
|
||||
ExpressCompile.Keyword.Boolean,
|
||||
out ExpTypeSource? type ) ?
|
||||
type : throw new ExpCompileNotInitializedException();
|
||||
|
||||
public override string TypeName => EqualityTypeConvert.Name;
|
||||
@@ -124,9 +124,9 @@ namespace StgSharp.Script.Express
|
||||
public float Value => _value;
|
||||
|
||||
public override IExpElementSource EqualityTypeConvert => ExpSchema.BuiltinSchema
|
||||
.TryGetType(
|
||||
ExpressCompile.KeyWord.String,
|
||||
out ExpTypeSource? type ) ?
|
||||
.TryGetType(
|
||||
ExpressCompile.Keyword.String,
|
||||
out ExpTypeSource? type ) ?
|
||||
type : throw new ExpCompileNotInitializedException();
|
||||
|
||||
public override string TypeName => EqualityTypeConvert.Name;
|
||||
@@ -148,9 +148,9 @@ namespace StgSharp.Script.Express
|
||||
public ExpLogic Value => _value;
|
||||
|
||||
public override IExpElementSource EqualityTypeConvert => ExpSchema.BuiltinSchema
|
||||
.TryGetType(
|
||||
ExpressCompile.KeyWord.Logical,
|
||||
out ExpTypeSource? type ) ?
|
||||
.TryGetType(
|
||||
ExpressCompile.Keyword.Logical,
|
||||
out ExpTypeSource? type ) ?
|
||||
type : throw new ExpCompileNotInitializedException();
|
||||
|
||||
public override string TypeName => EqualityTypeConvert.Name;
|
||||
|
||||
@@ -56,37 +56,20 @@ namespace StgSharp.Script.Express
|
||||
get { return ( _nodeFlag | ExpNodeFlag.BuiltinType_Number ) != 0; }
|
||||
}
|
||||
|
||||
public abstract ExpNode Left
|
||||
{
|
||||
get;
|
||||
}
|
||||
public abstract ExpNode Left { get; }
|
||||
|
||||
public static ExpNode Empty
|
||||
{
|
||||
get => ExpEmptyNode._only;
|
||||
}
|
||||
|
||||
public ExpNode Next
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public ExpNode Next { get; set; }
|
||||
|
||||
public abstract ExpNode Right
|
||||
{
|
||||
get;
|
||||
}
|
||||
public abstract ExpNode Right { get; }
|
||||
|
||||
public ExpNode Previous
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public ExpNode Previous { get; set; }
|
||||
|
||||
public abstract IExpElementSource EqualityTypeConvert
|
||||
{
|
||||
get;
|
||||
}
|
||||
public abstract IExpElementSource EqualityTypeConvert { get; }
|
||||
|
||||
public int Line => _source.Line;
|
||||
|
||||
@@ -94,10 +77,11 @@ namespace StgSharp.Script.Express
|
||||
|
||||
public long NodeFlag => ( long )_nodeFlag;
|
||||
|
||||
public string CodeConvertTemplate
|
||||
public string CodeConvertTemplate { get; init; }
|
||||
|
||||
public Token Source
|
||||
{
|
||||
get;
|
||||
init;
|
||||
get => _source;
|
||||
}
|
||||
|
||||
public void AppendNode( ExpNode nextNode )
|
||||
@@ -160,8 +144,7 @@ namespace StgSharp.Script.Express
|
||||
public ExpEmptyNode() : base( Token.Empty ) { }
|
||||
|
||||
public ExpEmptyNode( int line, int column )
|
||||
: base(
|
||||
new Token( string.Empty, line, column, TokenFlag.None ) ) { }
|
||||
: base( new Token( string.Empty, line, column, TokenFlag.None ) ) { }
|
||||
|
||||
public override ExpInstantiableElement EqualityTypeConvert => ExpInstantiableElement.Void;
|
||||
|
||||
|
||||
@@ -56,33 +56,36 @@ namespace StgSharp.Script.Express
|
||||
public abstract class ExpElementInstanceBase : ExpNode
|
||||
{
|
||||
|
||||
protected ExpElementInstanceBase( Token source ) : base( source ) { }
|
||||
|
||||
public ExpElementType ElementType
|
||||
protected ExpElementInstanceBase( Token source )
|
||||
: base( source )
|
||||
{
|
||||
get;
|
||||
CodeConvertTemplate = source.Value;
|
||||
}
|
||||
|
||||
public ExpElementType ElementType { get; }
|
||||
|
||||
public override ExpNode Left => Empty;
|
||||
|
||||
public override ExpNode Right => Empty;
|
||||
|
||||
public abstract string TypeName
|
||||
{
|
||||
get;
|
||||
}
|
||||
public abstract string TypeName { get; }
|
||||
|
||||
public static ExpElementInstanceBase CreateLiteral( Token t )
|
||||
{
|
||||
if( int.TryParse( t.Value, out int _int ) ) {
|
||||
if( int.TryParse( t.Value, out int _int ) )
|
||||
{
|
||||
return new ExpIntNode( t, _int );
|
||||
} else if( float.TryParse( t.Value, out float _float ) ) {
|
||||
} else if( float.TryParse( t.Value, out float _float ) )
|
||||
{
|
||||
return new ExpRealNumberNode( t, _float );
|
||||
} else if( bool.TryParse( t.Value, out bool _bool ) ) {
|
||||
} else if( bool.TryParse( t.Value, out bool _bool ) )
|
||||
{
|
||||
return new ExpBoolNode( t, _bool );
|
||||
} else if( ExpLogic.TryParse( t.Value, out ExpLogic _logic ) ) {
|
||||
} else if( ExpLogic.TryParse( t.Value, out ExpLogic _logic ) )
|
||||
{
|
||||
return new ExpLogicValueNode( t, _logic );
|
||||
} else {
|
||||
} else
|
||||
{
|
||||
return new ExpStringNode( t, t.Value );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ExpKeyword = StgSharp.Script.Express.ExpressCompile.KeyWord;
|
||||
using ExpKeyword = StgSharp.Script.Express.ExpressCompile.Keyword;
|
||||
|
||||
namespace StgSharp.Script.Express
|
||||
{
|
||||
@@ -43,15 +43,18 @@ namespace StgSharp.Script.Express
|
||||
|
||||
private bool TryParseBranch( Token t )
|
||||
{
|
||||
if( t.Value == ExpKeyword.Case ) {
|
||||
if( t.Value == ExpKeyword.Case )
|
||||
{
|
||||
_cache.PushOperator( t );
|
||||
_cache.IncreaseDepth( ( int )ExpCompileStateCode.CaseBranch );
|
||||
return true;
|
||||
} else if( t.Value == ExpKeyword.If ) {
|
||||
} else if( t.Value == ExpKeyword.If )
|
||||
{
|
||||
_cache.PushOperator( t );
|
||||
_cache.IncreaseDepth( ( int )ExpCompileStateCode.IfBranch );
|
||||
return true;
|
||||
} else if( t.Value == ExpKeyword.Repeat ) {
|
||||
} else if( t.Value == ExpKeyword.Repeat )
|
||||
{
|
||||
_cache.PushOperator( t );
|
||||
_cache.IncreaseDepth( ( int )ExpCompileStateCode.RepeatLoop );
|
||||
return true;
|
||||
|
||||
@@ -34,7 +34,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ExpKeyword = StgSharp.Script.Express.ExpressCompile.KeyWord;
|
||||
using ExpKeyword = StgSharp.Script.Express.ExpressCompile.Keyword;
|
||||
|
||||
namespace StgSharp.Script.Express
|
||||
{
|
||||
@@ -43,17 +43,16 @@ namespace StgSharp.Script.Express
|
||||
|
||||
public int CompareOperatorPrecedence( Token left, Token right )
|
||||
{
|
||||
ExpressCompile.TryGetOperatorPrecedence(
|
||||
left.Value, out int leftPrecedence );
|
||||
ExpressCompile.TryGetOperatorPrecedence(
|
||||
right.Value, out int rightPrecedence );
|
||||
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 ) {
|
||||
switch( t.Value )
|
||||
{
|
||||
case ExpKeyword.UnaryPlus:
|
||||
node = ExpUnaryOperatorNode.UnaryPlus( t, operand );
|
||||
return true;
|
||||
@@ -70,12 +69,13 @@ namespace StgSharp.Script.Express
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WARNING: This method cannot process INDEXOF, FUNCTION CALLING, LOOP and any ENDING
|
||||
/// SYMBOLS.
|
||||
/// WARNING: This method cannot process INDEXOF, FUNCTION CALLING, LOOP and any ENDING
|
||||
/// SYMBOLS.
|
||||
/// </summary>
|
||||
private ExpNode ConvertOneOperator( Token op )
|
||||
private ExpNode ConvertAndPushOneOperator( Token op )
|
||||
{
|
||||
switch( op.Flag ) {
|
||||
switch( op.Flag )
|
||||
{
|
||||
case TokenFlag.Symbol_Unary:
|
||||
TryGenerateUnaryNode( op, out ExpNode? node );
|
||||
_cache.PushOperand( node );
|
||||
@@ -85,31 +85,32 @@ namespace StgSharp.Script.Express
|
||||
_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 );
|
||||
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 {
|
||||
} 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 );
|
||||
} 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 {
|
||||
} else
|
||||
{
|
||||
throw new ExpCompileException(
|
||||
t,
|
||||
"An ExpNode for function calling is needed, but a token was popped" );
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
//uncertain case here
|
||||
@@ -121,9 +122,10 @@ namespace StgSharp.Script.Express
|
||||
|
||||
private bool TryGenerateBinaryNode( Token t, out ExpNode node )
|
||||
{
|
||||
ExpNode left = GetNextOperandCache();
|
||||
ExpNode right = GetNextOperandCache();
|
||||
switch( t.Value ) {
|
||||
ExpNode left = GetNextOperandCache();
|
||||
switch( t.Value )
|
||||
{
|
||||
case ExpKeyword.Add:
|
||||
node = ExpBinaryOperatorNode.Add( t, left, right );
|
||||
return true;
|
||||
@@ -148,6 +150,9 @@ namespace StgSharp.Script.Express
|
||||
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;
|
||||
|
||||
@@ -35,7 +35,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ExpKeyword = StgSharp.Script.Express.ExpressCompile.KeyWord;
|
||||
using ExpKeyword = StgSharp.Script.Express.ExpressCompile.Keyword;
|
||||
|
||||
namespace StgSharp.Script.Express
|
||||
{
|
||||
@@ -45,24 +45,24 @@ namespace StgSharp.Script.Express
|
||||
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" );
|
||||
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 ) {
|
||||
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( !_cache.TryPopOperand( out isNode, out Token t2, out ExpNode? n2 ) ) {
|
||||
throw new ExpCompileException( op, "No expression before a comma" );
|
||||
}
|
||||
if( !isNode ) {
|
||||
if( !isNode )
|
||||
{
|
||||
//On some occasions, a token may found,
|
||||
//but the processor is not implemented
|
||||
throw new NotImplementedException();
|
||||
@@ -71,20 +71,20 @@ namespace StgSharp.Script.Express
|
||||
_cache.PushOperand( n1 );
|
||||
continue;
|
||||
}
|
||||
ConvertOneOperator( op );
|
||||
|
||||
ExpNode node = GetNextOperandCache();
|
||||
_cache.PushOperand( node );
|
||||
ConvertAndPushOneOperator( op );
|
||||
}
|
||||
if( !_cache.TryPopOperand( out _, out _, out ExpNode? root ) ) {
|
||||
_cache.PushOperand( ExpNode.Empty );
|
||||
}
|
||||
_cache.DecreaseDepth();
|
||||
if( IsSeparatorMatch( _cache.PeekOperator(), rightSeparator ) ) {
|
||||
if( IsSeparatorMatch( _cache.PeekOperator(), rightSeparator ) )
|
||||
{
|
||||
_cache.PopOperator();
|
||||
} else {
|
||||
// some unexpected occasions
|
||||
throw new NotImplementedException();
|
||||
_cache.PushOperand( root );
|
||||
} else
|
||||
{
|
||||
throw new ExpCompileException(
|
||||
rightSeparator, "Ending of block soes not match its begging" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,26 +34,21 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ExpKeyword = StgSharp.Script.Express.ExpressCompile.KeyWord;
|
||||
using ExpKeyword = StgSharp.Script.Express.ExpressCompile.Keyword;
|
||||
|
||||
namespace StgSharp.Script.Express
|
||||
{
|
||||
public partial class ExpNodeGenerator
|
||||
{
|
||||
|
||||
private bool IsSeparatorMatch(
|
||||
Token leftSperator,
|
||||
Token rightSeparator )
|
||||
private bool IsSeparatorMatch( Token leftSperator, Token rightSeparator )
|
||||
{
|
||||
return leftSperator.Value switch
|
||||
{
|
||||
ExpKeyword.LeftBrace => rightSeparator.Value ==
|
||||
ExpKeyword.RightBrace,
|
||||
ExpKeyword.LeftParen => rightSeparator.Value ==
|
||||
ExpKeyword.RightParen,
|
||||
ExpKeyword.LeftBrace => rightSeparator.Value == ExpKeyword.RightBrace,
|
||||
ExpKeyword.LeftParen => rightSeparator.Value == ExpKeyword.RightParen,
|
||||
ExpKeyword.Comma => rightSeparator.Value == ExpKeyword.Comma,
|
||||
ExpKeyword.Semicolon => rightSeparator.Value ==
|
||||
ExpKeyword.Semicolon,
|
||||
ExpKeyword.Semicolon => rightSeparator.Value == ExpKeyword.Semicolon,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
@@ -63,8 +58,8 @@ namespace StgSharp.Script.Express
|
||||
if( t.Flag != TokenFlag.Index_Left ) {
|
||||
return false;
|
||||
}
|
||||
if( _cache.TryPeekOperand(
|
||||
out bool isNode, out _, out ExpNode? node ) ) {
|
||||
if( _cache.TryPeekOperand( out bool isNode, out _, out ExpNode? node ) )
|
||||
{
|
||||
if( node.EqualityTypeConvert is not ExpCollectionBase ) {
|
||||
ExpInvalidSyntaxException.ThrowNonCollectionIndex( t );
|
||||
}
|
||||
@@ -85,8 +80,7 @@ namespace StgSharp.Script.Express
|
||||
|
||||
//make index node
|
||||
_cache.PopOperand( out _, out ExpNode? expNode );
|
||||
if( !_cache.PopOperand(
|
||||
out Token colleToken, out ExpNode? colleNode ) ) { }
|
||||
if( !_cache.PopOperand( out Token colleToken, out ExpNode? colleNode ) ) { }
|
||||
_cache.PushOperand(
|
||||
ExpCollectionIndexNode.Create(
|
||||
t, ( colleNode as ExpCollectionInstanceBase )!, expNode ) );
|
||||
@@ -120,27 +114,32 @@ namespace StgSharp.Script.Express
|
||||
if( t.Flag != TokenFlag.Separator_Middle ) {
|
||||
return false;
|
||||
}
|
||||
if( _cache.OperatorAheadOfDepth == 0 ) {
|
||||
if( _cache.OperandAheadOfDepth == 1 ) {
|
||||
if( _cache.OperatorAheadOfDepth == 0 )
|
||||
{
|
||||
if( _cache.OperandAheadOfDepth == 1 )
|
||||
{
|
||||
_cache.PushOperand( t );
|
||||
_cache.PushOperator( t );
|
||||
return true;
|
||||
} else {
|
||||
} else
|
||||
{
|
||||
ExpInvalidSyntaxException.ThrowNoOperator( t );
|
||||
}
|
||||
}
|
||||
Token op;
|
||||
processOperator:
|
||||
if( _cache.TryPopOperator( out op ) ) {
|
||||
if( op.Value == t.Value ) {
|
||||
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 = ConvertOneOperator( op );
|
||||
_cache.PushOperand( node );
|
||||
} else
|
||||
{
|
||||
ExpNode node = ConvertAndPushOneOperator( op );
|
||||
goto processOperator;
|
||||
}
|
||||
}
|
||||
@@ -161,6 +160,7 @@ namespace StgSharp.Script.Express
|
||||
if( t.Flag != TokenFlag.Separator_Left ) {
|
||||
return false;
|
||||
}
|
||||
_cache.PushOperator( t );
|
||||
_cache.IncreaseDepth( ( int )ExpCompileStateCode.PrefixSeparator );
|
||||
return true;
|
||||
}
|
||||
@@ -176,31 +176,35 @@ namespace StgSharp.Script.Express
|
||||
|
||||
private bool TryAppendSymbol( Token t )
|
||||
{
|
||||
if( ( t.Flag & ( TokenFlag.Symbol_Unary | TokenFlag.Symbol_Binary ) ) ==
|
||||
0 ) {
|
||||
if( ( t.Flag & ( TokenFlag.Symbol_Unary | TokenFlag.Symbol_Binary ) ) == 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int cmp = -1;
|
||||
processPrecedence:
|
||||
if( _cache.TryPopOperator( out Token tmp ) ) {
|
||||
if( _cache.TryPeekOperator( out Token tmp ) )
|
||||
{
|
||||
cmp = CompareOperatorPrecedence( t, tmp );
|
||||
if( cmp <= 0 ) {
|
||||
ExpNode node = ConvertOneOperator( tmp );
|
||||
if( cmp >= 0 )
|
||||
{
|
||||
_cache.PopOperator();
|
||||
ExpNode node = ConvertAndPushOneOperator( tmp );
|
||||
_cache.PushOperand( node );
|
||||
goto processPrecedence;
|
||||
}
|
||||
}
|
||||
_cache.PushOperand( t );
|
||||
_cache.PushOperator( t );
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TryParseConstant( Token t )
|
||||
{
|
||||
if( t.Value == ExpKeyword.True ) {
|
||||
if( t.Value == ExpKeyword.True )
|
||||
{
|
||||
_cache.PushOperand( new ExpBoolNode( t, true ) );
|
||||
return true;
|
||||
} else if( t.Value == ExpKeyword.False ) {
|
||||
} else if( t.Value == ExpKeyword.False )
|
||||
{
|
||||
_cache.PushOperand( new ExpBoolNode( t, false ) );
|
||||
return true;
|
||||
}
|
||||
@@ -209,11 +213,12 @@ namespace StgSharp.Script.Express
|
||||
|
||||
private bool TryParseFunction( Token t )
|
||||
{
|
||||
if( ExpKeyword.BuiltinFunctions.Contains( t.Value ) ) {
|
||||
if( ExpKeyword.BuiltinFunctions.Contains( t.Value ) )
|
||||
{
|
||||
_cache.PushOperator( t );
|
||||
return true;
|
||||
} else if( _context.TryGetFunction(
|
||||
t.Value, out ExpFunctionSource? f ) ) {
|
||||
} else if( _context.TryGetFunction( t.Value, out ExpFunctionSource? f ) )
|
||||
{
|
||||
_cache.PushOperand( t );
|
||||
return true;
|
||||
}
|
||||
@@ -223,9 +228,9 @@ namespace StgSharp.Script.Express
|
||||
private bool TryParseInstance( Token t )
|
||||
{
|
||||
if( _local.TryGetMember( t.Value,
|
||||
out ExpNode? node ) && node is ExpElementInstanceBase instance ) {
|
||||
_cache.PushOperand(
|
||||
ExpInstanceReferenceNode.Create( t, instance ) );
|
||||
out ExpNode? node ) && node is ExpElementInstanceBase instance )
|
||||
{
|
||||
_cache.PushOperand( ExpInstanceReferenceNode.Create( t, instance ) );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -40,7 +40,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ExpKeyword = StgSharp.Script.Express.ExpressCompile.KeyWord;
|
||||
using ExpKeyword = StgSharp.Script.Express.ExpressCompile.Keyword;
|
||||
|
||||
namespace StgSharp.Script.Express
|
||||
{
|
||||
@@ -67,9 +67,11 @@ namespace StgSharp.Script.Express
|
||||
{
|
||||
_cache = new CompileStack<ExpNode, IExpElementSource>();
|
||||
ArgumentNullException.ThrowIfNull( context );
|
||||
if( context is not ExpSchema_Builtin ) {
|
||||
if( context is not ExpSchema_Builtin )
|
||||
{
|
||||
_context = context;
|
||||
} else {
|
||||
} else
|
||||
{
|
||||
throw new InvalidCastException( "Not a valid Schema type" );
|
||||
}
|
||||
_local = local;
|
||||
@@ -78,12 +80,13 @@ namespace StgSharp.Script.Express
|
||||
/**/
|
||||
|
||||
/// <summary>
|
||||
/// Append a token to top of cache. This method will automatically convert token to node if
|
||||
/// meets separators or operators.
|
||||
/// 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 ) {
|
||||
switch( expToken.Flag )
|
||||
{
|
||||
case TokenFlag.Symbol_Unary or TokenFlag.Symbol_Binary:
|
||||
TryAppendSymbol( expToken );
|
||||
break;
|
||||
@@ -112,7 +115,8 @@ namespace StgSharp.Script.Express
|
||||
|
||||
public ExpNode GetNextOperandCache()
|
||||
{
|
||||
if( _cache.PopOperand( out Token t, out ExpNode? n ) ) {
|
||||
if( _cache.PopOperand( out Token t, out ExpNode? n ) )
|
||||
{
|
||||
return n;
|
||||
} else { }
|
||||
|
||||
|
||||
@@ -189,7 +189,7 @@ namespace StgSharp.Script.Express
|
||||
begin = _current;
|
||||
_current++;
|
||||
_last = new Token(
|
||||
ExpressCompile.PoolString( ")" ), _lineNum, begin,
|
||||
ExpressCompile.PoolString( source[ ..1 ] ), _lineNum, begin,
|
||||
TokenFlag.Separator_Right );
|
||||
return _last;
|
||||
case '-':
|
||||
@@ -267,13 +267,14 @@ namespace StgSharp.Script.Express
|
||||
begin = _current;
|
||||
_current += 2;
|
||||
return new Token(
|
||||
ExpressCompile.KeyWord.Assignment, _lineNum, begin,
|
||||
TokenFlag.Index_Right );
|
||||
ExpressCompile.Keyword.Assignment, _lineNum, begin,
|
||||
TokenFlag.Symbol_Binary );
|
||||
}
|
||||
begin = _current;
|
||||
_current++;
|
||||
return new Token(
|
||||
ExpressCompile.KeyWord.Colon, _lineNum, begin, TokenFlag.Index_Right );
|
||||
ExpressCompile.Keyword.Colon, _lineNum, begin,
|
||||
TokenFlag.Separator_Middle );
|
||||
case '+' or '/' or '\\' or '*' or '.':
|
||||
begin = _current;
|
||||
_current++;
|
||||
@@ -293,16 +294,7 @@ namespace StgSharp.Script.Express
|
||||
rest = match.Groups[ RestMark ].Index;
|
||||
_current = rest;
|
||||
string str = ExpressCompile.PoolString( source[ ..( end - begin ) ] );
|
||||
TokenFlag flag;
|
||||
if( ReferenceEquals( str, ExpressCompile.KeyWord.Not ) )
|
||||
{
|
||||
flag = TokenFlag.Symbol_Unary;
|
||||
} else
|
||||
{
|
||||
flag = ExpressCompile.LetterIsOperator( str ) ?
|
||||
TokenFlag.Symbol_Binary : TokenFlag.Member;
|
||||
}
|
||||
return new( str, _lineNum, begin, flag );
|
||||
return new( str, _lineNum, begin, TokenFlag.Number );
|
||||
} else
|
||||
{
|
||||
throw new ExpInvalidTokenException( _current );
|
||||
|
||||
Reference in New Issue
Block a user