├── src ├── .editorconfig ├── GDShrapt.Reader │ ├── SimpleTokens │ │ ├── IGDStructureToken.cs │ │ ├── GDPairToken.cs │ │ ├── Keywords │ │ │ ├── GDKeyword.cs │ │ │ ├── GDBoolKeyword.cs │ │ │ ├── GDIfKeyword_.cs │ │ │ ├── GDInKeyword.cs │ │ │ ├── GDArrayKeyword.cs │ │ │ ├── GDForKeyword.cs │ │ │ ├── GDGetKeyword.cs │ │ │ ├── GDSetKeyword.cs │ │ │ ├── GDVarKeyword.cs │ │ │ ├── GDYieldKeyword.cs │ │ │ ├── GDAwaitKeyword.cs │ │ │ ├── GDBreakKeyword.cs │ │ │ ├── GDClassKeyword.cs │ │ │ ├── GDConstKeyword.cs │ │ │ ├── GDElifKeyword.cs │ │ │ ├── GDElseKeyword.cs │ │ │ ├── GDEnumKeyword.cs │ │ │ ├── GDFuncKeyword.cs │ │ │ ├── GDMatchKeyword.cs │ │ │ ├── GDPassKeyword.cs │ │ │ ├── GDToolKeyword.cs │ │ │ ├── GDWhenKeyword.cs │ │ │ ├── GDWhileKeyword.cs │ │ │ ├── GDExportKeyword.cs │ │ │ ├── GDReturnKeyword.cs │ │ │ ├── GDSetGetKeyword.cs │ │ │ ├── GDSignalKeyword.cs │ │ │ ├── GDStaticKeyword.cs │ │ │ ├── GDExtendsKeyword.cs │ │ │ ├── GDOnreadyKeyword.cs │ │ │ ├── GDContinueKeyword.cs │ │ │ ├── GDReturnTypeKeyword.cs │ │ │ ├── GDBreakPointKeyword.cs │ │ │ ├── GDClassNameKeyword.cs │ │ │ ├── GDDictionaryKeyword.cs │ │ │ ├── GDFalseKeyword.cs │ │ │ └── GDTrueKeyword.cs │ │ ├── GDAt.cs │ │ ├── GDSky.cs │ │ ├── GDDollar.cs │ │ ├── GDPercent.cs │ │ ├── GDAssign.cs │ │ ├── GDColon.cs │ │ ├── GDDoubleQuotas.cs │ │ ├── GDLeftSlash.cs │ │ ├── GDRightSlash.cs │ │ ├── GDSingleQuotas.cs │ │ ├── GDComma.cs │ │ ├── GDDefaultToken.cs │ │ ├── GDPoint.cs │ │ ├── GDSemiColon.cs │ │ ├── GDOpenBracket.cs │ │ ├── GDCloseBracket.cs │ │ ├── GDTripleDoubleQuotas.cs │ │ ├── GDTripleSingleQuotas.cs │ │ ├── GDCornerOpenBracket.cs │ │ ├── GDFigureOpenBracket.cs │ │ ├── GDSquareOpenBracket.cs │ │ ├── GDCornerCloseBracket.cs │ │ ├── GDFigureCloseBracket.cs │ │ ├── GDSquareCloseBracket.cs │ │ ├── GDNewLine.cs │ │ ├── GDDualOperator.cs │ │ ├── GDSingleOperator.cs │ │ ├── GDInvalidToken.cs │ │ ├── GDSpace.cs │ │ ├── GDPathSpecifier.cs │ │ ├── GDComment.cs │ │ ├── GDMultiLineSplitToken.cs │ │ ├── GDStringPart.cs │ │ ├── GDIntendation.cs │ │ └── GDExternalName.cs │ ├── Basics │ │ ├── GDSideType.cs │ │ ├── GDPathBoundingChar.cs │ │ ├── GDPathSpecifierType.cs │ │ ├── Receiving │ │ │ ├── INewLineReceiver.cs │ │ │ ├── ITokenOrSkipReceiver.cs │ │ │ ├── ITokenSkipReceiver.cs │ │ │ ├── IIntendedTokenReceiver.cs │ │ │ └── ITokenReceiver.cs │ │ ├── GDAssociationOrderType.cs │ │ ├── GDNumberType.cs │ │ ├── GDSingleOperatorType.cs │ │ ├── GDStringBoundingChar.cs │ │ ├── GDIntendedNode.cs │ │ ├── GDOperationType.cs │ │ ├── GDNameToken.cs │ │ ├── IGDNode.cs │ │ ├── IGDClassDeclaration.cs │ │ ├── GDLiteralToken.cs │ │ ├── GDSimpleSyntaxToken.cs │ │ ├── GDDualOperatorType.cs │ │ ├── GDSequenceToken.cs │ │ ├── GDSingleCharToken.cs │ │ ├── GDReader.cs │ │ └── GDCharSequence.cs │ ├── Walking │ │ ├── IGDBaseVisitor.cs │ │ └── GDBaseVisitor.cs │ ├── GDProject.cs │ ├── Types │ │ ├── GDTypeNode.cs │ │ ├── GDSingleTypeNode.cs │ │ └── GDStringTypeNode.cs │ ├── Atributes │ │ ├── GDClassAttribute.cs │ │ ├── GDToolAttribute.cs │ │ ├── GDCustomAttribute.cs │ │ ├── GDExtendsAttribute.cs │ │ └── GDClassNameAttribute.cs │ ├── Declarations │ │ ├── Property │ │ │ └── GDAccessorDeclaration.cs │ │ └── Class │ │ │ ├── GDIdentifiableClassMember.cs │ │ │ └── GDClassMember.cs │ ├── Statements │ │ ├── GDStatement.cs │ │ └── GDExpressionStatement.cs │ ├── GDInvalidStateException.cs │ ├── SystemExtensionMethods.cs │ ├── Resolvers │ │ ├── GDResolver.cs │ │ ├── GDKeywordResolver.cs │ │ ├── GDSequenceTokenResolver.cs │ │ ├── GDStartTrimmingResolver.cs │ │ ├── GDElifResolver.cs │ │ ├── GDElseResolver.cs │ │ ├── GDSingleCharTokenResolver.cs │ │ ├── GDStringNodeResolver.cs │ │ ├── GDSingleOperatorResolver.cs │ │ ├── GDSequenceResolver.cs │ │ ├── GDMatchCasesResolver.cs │ │ ├── GDIntendedSequenceResolver.cs │ │ └── GDDictionaryKeyValueResolver.cs │ ├── Lists │ │ ├── GDIntendedTokensList.cs │ │ ├── GDEnumValuesList.cs │ │ ├── GDParametersList.cs │ │ ├── GDExpressionsList.cs │ │ ├── GDElifBranchesList.cs │ │ ├── GDDictionaryKeyValueDeclarationList.cs │ │ ├── GDMatchCasesList.cs │ │ ├── GDClassMembersList.cs │ │ ├── GDCommaSeparatedList.cs │ │ ├── GDStatementsList.cs │ │ ├── GDLayersList.cs │ │ ├── GDStringPartsList.cs │ │ └── GDSeparatedList.cs │ ├── GDReadSettings.cs │ ├── GDTokensContainer.cs │ ├── GDShrapt.Reader.csproj │ ├── GDReceiver.cs │ ├── Building │ │ ├── GD_KEYWORDS.cs │ │ ├── GD_ATRIBUTE.cs │ │ └── GDBuildingExtensionMethods_KEYWORDS.cs │ └── Expressions │ │ ├── GDPassExpression.cs │ │ ├── GDBreakExpression.cs │ │ ├── GDContinueExpression.cs │ │ ├── GDMatchDefaultOperatorExpression.cs │ │ ├── GDBreakPointExpression.cs │ │ ├── GDStringExpression.cs │ │ ├── GDNumberExpression.cs │ │ ├── GDIdentifierExpression.cs │ │ ├── GDBoolExpression.cs │ │ ├── GDNodePathExpression.cs │ │ ├── GDGetNodeExpression.cs │ │ ├── GDGetUniqueNodeExpression.cs │ │ └── GDMatchCaseVariableExpression.cs ├── GDShrapt.Reader.Tests │ ├── TestingExtensionMethods.cs │ ├── Scripts │ │ ├── Sample4.gd │ │ ├── Sample5.gd │ │ └── Sample3.gd │ ├── GDShrapt.Reader.Tests.csproj │ ├── AssertHelper.cs │ ├── InvalidTokenTests.cs │ └── BigScriptTests.cs └── GDShrapt.sln ├── .github ├── workflows │ └── dotnet.yml └── FUNDING.yml └── LICENSE /src/.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | indent_style = space 3 | indent_size = 4 4 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/IGDStructureToken.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | internal interface IGDStructureToken 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDPairToken.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public abstract class GDPairToken : GDSingleCharToken 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/GDSideType.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public enum GDSideType 4 | { 5 | Left, 6 | Right 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public abstract class GDKeyword : GDSequenceToken 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/GDPathBoundingChar.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public enum GDPathBoundingChar 4 | { 5 | None, 6 | SingleQuotas, 7 | DoubleQuotas 8 | } 9 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/GDPathSpecifierType.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public enum GDPathSpecifierType 4 | { 5 | Current, 6 | Parent, 7 | Identifier 8 | } 9 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Walking/IGDBaseVisitor.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public interface IGDBaseVisitor 4 | { 5 | void EnterNode(GDNode node); 6 | void LeftNode(); 7 | } 8 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/Receiving/INewLineReceiver.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public interface INewLineReceiver : ITokenReceiver 4 | { 5 | void HandleReceivedToken(GDNewLine token); 6 | } 7 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDBoolKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public abstract class GDBoolKeyword : GDKeyword 4 | { 5 | public abstract bool Value { get; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/Receiving/ITokenOrSkipReceiver.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public interface ITokenOrSkipReceiver : ITokenReceiver, ITokenSkipReceiver 4 | where T : GDSyntaxToken 5 | { 6 | } 7 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/GDAssociationOrderType.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public enum GDAssociationOrderType 4 | { 5 | Undefined = 0, 6 | FromLeftToRight, 7 | FromRightToLeft 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/GDProject.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace GDShrapt.Reader 4 | { 5 | public class GDProject 6 | { 7 | public List Classes { get; } = new List(); 8 | } 9 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/GDNumberType.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public enum GDNumberType 4 | { 5 | Undefined, 6 | LongDecimal, 7 | LongBinary, 8 | LongHexadecimal, 9 | Double 10 | } 11 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/Receiving/ITokenSkipReceiver.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public interface ITokenSkipReceiver : ITokenReceiver 4 | where T : GDSyntaxToken 5 | { 6 | void HandleReceivedTokenSkip(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/GDSingleOperatorType.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public enum GDSingleOperatorType 4 | { 5 | Null = 0, 6 | Negate, 7 | Not, 8 | Not2, 9 | BitwiseNegate, 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/GDStringBoundingChar.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public enum GDStringBoundingChar 4 | { 5 | SingleQuotas, 6 | DoubleQuotas, 7 | TripleDoubleQuotas, 8 | TripleSingleQuotas 9 | } 10 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Types/GDTypeNode.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public abstract class GDTypeNode : GDNode 4 | { 5 | public abstract bool IsArray { get; } 6 | public abstract bool IsDictionary { get; } 7 | public abstract string BuildName(); 8 | } 9 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDAt.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDAt : GDSingleCharToken 4 | { 5 | public override char Char => '@'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDAt(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDSky.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDSky : GDSingleCharToken 4 | { 5 | public override char Char => '^'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDSky(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDDollar.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDDollar : GDSingleCharToken 4 | { 5 | public override char Char => '$'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDDollar(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDPercent.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDPercent : GDSingleCharToken 4 | { 5 | public override char Char => '%'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDPercent(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDAssign.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDAssign : GDPairToken, IGDStructureToken 4 | { 5 | public override char Char => '='; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDAssign(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDColon.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDColon : GDPairToken, IGDStructureToken 4 | { 5 | public override char Char => ':'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDColon(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDDoubleQuotas.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public class GDDoubleQuotas : GDSingleCharToken 4 | { 5 | public override char Char => '"'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDDoubleQuotas(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDLeftSlash.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDLeftSlash : GDSingleCharToken 4 | { 5 | public override char Char => '\\'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDLeftSlash(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDRightSlash.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDRightSlash : GDSingleCharToken 4 | { 5 | public override char Char => '/'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDRightSlash(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDSingleQuotas.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public class GDSingleQuotas : GDSingleCharToken 4 | { 5 | public override char Char => '\''; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDSingleQuotas(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDComma.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDComma : GDSingleCharToken, IGDStructureToken 4 | { 5 | public override char Char => ','; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDComma(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDDefaultToken.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDDefaultToken : GDSingleCharToken 4 | { 5 | public override char Char => '_'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDDefaultToken(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDPoint.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDPoint : GDSingleCharToken, IGDStructureToken 4 | { 5 | public override char Char => '.'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDPoint(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDIfKeyword_.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDIfKeyword : GDKeyword 4 | { 5 | public override string Sequence => "if"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDIfKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDInKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDInKeyword : GDKeyword 4 | { 5 | public override string Sequence => "in"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDInKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDArrayKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDArrayKeyword : GDKeyword 4 | { 5 | public override string Sequence => "Array"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDArrayKeyword(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDForKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDForKeyword : GDKeyword 4 | { 5 | public override string Sequence => "for"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDForKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDGetKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDGetKeyword : GDKeyword 4 | { 5 | public override string Sequence => "get"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDGetKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDSetKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDSetKeyword : GDKeyword 4 | { 5 | public override string Sequence => "set"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDSetKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDVarKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDVarKeyword : GDKeyword 4 | { 5 | public override string Sequence => "var"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDVarKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDYieldKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDYieldKeyword : GDKeyword 4 | { 5 | public override string Sequence => "yield"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDYieldKeyword(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDSemiColon.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDSemiColon : GDSingleCharToken, IGDStructureToken 4 | { 5 | public override char Char => ';'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDSemiColon(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDAwaitKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDAwaitKeyword : GDKeyword 4 | { 5 | public override string Sequence => "await"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDAwaitKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDBreakKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDBreakKeyword : GDKeyword 4 | { 5 | public override string Sequence => "break"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDBreakKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDClassKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDClassKeyword : GDKeyword 4 | { 5 | public override string Sequence => "class"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDClassKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDConstKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDConstKeyword : GDKeyword 4 | { 5 | public override string Sequence => "const"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDConstKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDElifKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDElifKeyword : GDKeyword 4 | { 5 | public override string Sequence => "elif"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDElifKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDElseKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDElseKeyword : GDKeyword 4 | { 5 | public override string Sequence => "else"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDElseKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDEnumKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDEnumKeyword : GDKeyword 4 | { 5 | public override string Sequence => "enum"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDEnumKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDFuncKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDFuncKeyword : GDKeyword 4 | { 5 | public override string Sequence => "func"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDFuncKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDMatchKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDMatchKeyword : GDKeyword 4 | { 5 | public override string Sequence => "match"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDMatchKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDPassKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDPassKeyword : GDKeyword 4 | { 5 | public override string Sequence => "pass"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDPassKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDToolKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDToolKeyword : GDKeyword 4 | { 5 | public override string Sequence => "tool"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDToolKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDWhenKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDWhenKeyword : GDKeyword 4 | { 5 | public override string Sequence => "when"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDWhenKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDWhileKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDWhileKeyword : GDKeyword 4 | { 5 | public override string Sequence => "while"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDWhileKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Atributes/GDClassAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public abstract class GDClassAttribute : GDClassMember 4 | { 5 | internal GDClassAttribute() 6 | { 7 | } 8 | 9 | internal GDClassAttribute(int intendation) 10 | : base(intendation) 11 | { 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDOpenBracket.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDOpenBracket : GDSingleCharToken, IGDStructureToken 4 | { 5 | public override char Char => '('; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDOpenBracket(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDExportKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDExportKeyword : GDKeyword 4 | { 5 | public override string Sequence => "export"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDExportKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDReturnKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDReturnKeyword : GDKeyword 4 | { 5 | public override string Sequence => "return"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDReturnKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDSetGetKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDSetGetKeyword : GDKeyword 4 | { 5 | public override string Sequence => "setget"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDSetGetKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDSignalKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDSignalKeyword : GDKeyword 4 | { 5 | public override string Sequence => "signal"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDSignalKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDStaticKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDStaticKeyword : GDKeyword 4 | { 5 | public override string Sequence => "static"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDStaticKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDCloseBracket.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDCloseBracket : GDSingleCharToken, IGDStructureToken 4 | { 5 | public override char Char => ')'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDCloseBracket(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDTripleDoubleQuotas.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public class GDTripleDoubleQuotas : GDSequenceToken 4 | { 5 | public override string Sequence => "\"\"\""; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDTripleDoubleQuotas(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDTripleSingleQuotas.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public class GDTripleSingleQuotas : GDSequenceToken 4 | { 5 | public override string Sequence => "'''"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDTripleSingleQuotas(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDExtendsKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDExtendsKeyword : GDKeyword 4 | { 5 | public override string Sequence => "extends"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDExtendsKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDOnreadyKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDOnreadyKeyword : GDKeyword 4 | { 5 | public override string Sequence => "onready"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDOnreadyKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDContinueKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDContinueKeyword : GDKeyword 4 | { 5 | public override string Sequence => "continue"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDContinueKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDReturnTypeKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDReturnTypeKeyword : GDKeyword 4 | { 5 | public override string Sequence => "->"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDReturnTypeKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDBreakPointKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDBreakPointKeyword : GDKeyword 4 | { 5 | public override string Sequence => "breakpoint"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDBreakPointKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDClassNameKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDClassNameKeyword : GDKeyword 4 | { 5 | public override string Sequence => "class_name"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDClassNameKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDDictionaryKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDDictionaryKeyword : GDKeyword 4 | { 5 | public override string Sequence => "Dictionary"; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDDictionaryKeyword(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDCornerOpenBracket.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDCornerOpenBracket : GDSingleCharToken, IGDStructureToken 4 | { 5 | public override char Char => '<'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDCornerOpenBracket(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDFigureOpenBracket.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDFigureOpenBracket : GDSingleCharToken, IGDStructureToken 4 | { 5 | public override char Char => '{'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDFigureOpenBracket(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDSquareOpenBracket.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDSquareOpenBracket : GDSingleCharToken, IGDStructureToken 4 | { 5 | public override char Char => '['; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDSquareOpenBracket(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDCornerCloseBracket.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDCornerCloseBracket : GDSingleCharToken, IGDStructureToken 4 | { 5 | public override char Char => '>'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDCornerCloseBracket(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDFigureCloseBracket.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDFigureCloseBracket : GDSingleCharToken, IGDStructureToken 4 | { 5 | public override char Char => '}'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDFigureCloseBracket(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDSquareCloseBracket.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDSquareCloseBracket : GDSingleCharToken, IGDStructureToken 4 | { 5 | public override char Char => ']'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDSquareCloseBracket(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Declarations/Property/GDAccessorDeclaration.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public abstract class GDAccessorDeclaration : GDIntendedNode 4 | { 5 | internal GDAccessorDeclaration() 6 | { 7 | } 8 | 9 | internal GDAccessorDeclaration(int intendation) 10 | : base(intendation) 11 | { 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDFalseKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDFalseKeyword : GDBoolKeyword 4 | { 5 | public override string Sequence => "false"; 6 | public override bool Value => false; 7 | 8 | public override GDSyntaxToken Clone() 9 | { 10 | return new GDFalseKeyword(); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/Keywords/GDTrueKeyword.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDTrueKeyword : GDBoolKeyword 4 | { 5 | public override string Sequence => "true"; 6 | 7 | public override bool Value => true; 8 | 9 | public override GDSyntaxToken Clone() 10 | { 11 | return new GDTrueKeyword(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader.Tests/TestingExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | 3 | namespace GDShrapt.Reader.Tests 4 | { 5 | public static class TestingExtensionMethods 6 | { 7 | 8 | public static T CastOrAssert(this object self) 9 | { 10 | Assert.IsInstanceOfType(self, typeof(T)); 11 | return (T)self; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDNewLine.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDNewLine : GDSingleCharToken 4 | { 5 | public override char Char => '\n'; 6 | 7 | public override GDSyntaxToken Clone() 8 | { 9 | return new GDNewLine(); 10 | } 11 | 12 | public override int NewLinesCount => 1; 13 | public override int Length => 0; 14 | public override int EndColumn => 0; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Declarations/Class/GDIdentifiableClassMember.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public abstract class GDIdentifiableClassMember : GDClassMember 4 | { 5 | public abstract GDIdentifier Identifier { get; set; } 6 | public abstract bool IsStatic { get; } 7 | 8 | internal GDIdentifiableClassMember(int intendation) 9 | : base(intendation) 10 | { 11 | } 12 | 13 | internal GDIdentifiableClassMember() 14 | : base() 15 | { 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/Receiving/IIntendedTokenReceiver.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public interface IIntendedTokenOrSkipReceiver : IIntendedTokenReceiver, ITokenOrSkipReceiver 4 | where T : GDSyntaxToken 5 | { 6 | } 7 | 8 | public interface IIntendedTokenReceiver : IIntendedTokenReceiver, ITokenReceiver 9 | where T : GDSyntaxToken 10 | { 11 | } 12 | 13 | public interface IIntendedTokenReceiver : INewLineReceiver, ITokenReceiver 14 | { 15 | void HandleReceivedToken(GDIntendation token); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.github/workflows/dotnet.yml: -------------------------------------------------------------------------------- 1 | name: .NET 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Setup .NET 17 | uses: actions/setup-dotnet@v1 18 | with: 19 | dotnet-version: 5.0.x 20 | - name: Restore dependencies 21 | run: dotnet restore src 22 | - name: Build 23 | run: dotnet build src --no-restore 24 | - name: Test 25 | run: dotnet test src --no-build --verbosity normal 26 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/GDIntendedNode.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public abstract class GDIntendedNode : GDNode, ITokenReceiver 4 | { 5 | internal int Intendation { get; } 6 | 7 | internal GDIntendedNode(int intendation) 8 | { 9 | Intendation = intendation; 10 | } 11 | 12 | internal GDIntendedNode() 13 | { 14 | } 15 | 16 | void ITokenReceiver.HandleReceivedToken(GDIntendation token) 17 | { 18 | Form.AddBeforeActiveToken(token); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/Receiving/ITokenReceiver.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public interface ITokenReceiver : ITokenReceiver 4 | where T : GDSyntaxToken 5 | { 6 | void HandleReceivedToken(T token); 7 | } 8 | 9 | 10 | public interface ITokenReceiver 11 | { 12 | void HandleReceivedToken(GDComment token); 13 | void HandleReceivedToken(GDSpace token); 14 | void HandleReceivedToken(GDAttribute token); 15 | void HandleReceivedToken(GDInvalidToken token); 16 | void HandleReceivedToken(GDMultiLineSplitToken token); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: elamaunt 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: #['',''] 13 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/GDOperationType.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public enum GDOperationType 4 | { 5 | Literal, 6 | ArrayInitializer, 7 | Brackets, 8 | Call, 9 | Identifier, 10 | Member, 11 | Parameters, 12 | Indexer, 13 | Return, 14 | Pass, 15 | MatchCaseVariable, 16 | DictionaryInitializer, 17 | GetUniqueNode, 18 | GetNode, 19 | NodePath, 20 | If, 21 | Continue, 22 | DefaultOperator, 23 | Breakpoint, 24 | Break, 25 | Yeild, 26 | Await, 27 | Method 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader.Tests/Scripts/Sample4.gd: -------------------------------------------------------------------------------- 1 | class_name ChooseDeck 2 | extends Control 3 | 4 | @export var deckEntryScene: PackedScene 5 | @export var deckBuilderScene: PackedScene 6 | 7 | signal deck_choosen(deck: int) 8 | 9 | func setup(decks: Array[DeckData]): 10 | for deckVar in decks: 11 | var deck := deckVar as DeckData 12 | var deckEntry = deckEntryScene.instantiate() as DeckEntry 13 | $FlowContainer.add_child(deckEntry) 14 | deckEntry.setup(deck.Name, deck.Id, self) 15 | 16 | func choose_deck() -> int: 17 | visible = true 18 | var deckId = await deck_choosen 19 | visible = false 20 | return deckId 21 | 22 | func new_deck() -> void: 23 | SceneLoader.goto_deckbuilder(true) -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Statements/GDStatement.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public abstract class GDStatement : GDIntendedNode 4 | { 5 | /// 6 | /// The count of '\t' before the statement 7 | /// 8 | internal int LineIntendation { get; } 9 | 10 | 11 | /// 12 | /// Internal constructor to parse intendation incerement properly 13 | /// 14 | /// 15 | internal GDStatement(int lineIntendation) 16 | { 17 | LineIntendation = lineIntendation; 18 | } 19 | 20 | public GDStatement() 21 | { 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/GDNameToken.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public abstract class GDNameToken : GDSimpleSyntaxToken 4 | { 5 | /// 6 | /// Throws ArgumentException if set invalid format value 7 | /// 8 | public abstract string Sequence { get; set; } 9 | 10 | public override int GetHashCode() 11 | { 12 | return Sequence?.GetHashCode() ?? base.GetHashCode(); 13 | } 14 | 15 | public override bool Equals(object obj) 16 | { 17 | if (obj is GDLiteralToken other) 18 | return string.Equals(Sequence, other.Sequence); 19 | return base.Equals(obj); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/IGDNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace GDShrapt.Reader 4 | { 5 | public interface IGDNode : IGDSyntaxToken 6 | { 7 | IEnumerable Nodes { get; } 8 | IEnumerable NodesReversed { get; } 9 | IEnumerable AllNodes { get; } 10 | IEnumerable AllNodesReversed { get; } 11 | IEnumerable AllTokens { get; } 12 | IEnumerable AllTokensReversed { get; } 13 | 14 | int TokensCount { get; } 15 | bool HasTokens { get; } 16 | GDTokensForm Form { get; } 17 | GDSyntaxToken[] FormTokensSetter { set; } 18 | 19 | void UpdateIntendation(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDDualOperator.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDDualOperator : GDSimpleSyntaxToken 4 | { 5 | public GDDualOperatorType OperatorType { get; set; } 6 | 7 | internal override void HandleChar(char c, GDReadingState state) 8 | { 9 | state.Pop(); 10 | state.PassChar(c); 11 | } 12 | 13 | public override GDSyntaxToken Clone() 14 | { 15 | return new GDDualOperator() 16 | { 17 | OperatorType = OperatorType 18 | }; 19 | } 20 | 21 | public override string ToString() 22 | { 23 | return OperatorType.Print(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/GDInvalidStateException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace GDShrapt.Reader 5 | { 6 | public class GDInvalidStateException : Exception 7 | { 8 | public GDInvalidStateException() 9 | { 10 | } 11 | 12 | public GDInvalidStateException(string message) 13 | : base(message) 14 | { 15 | } 16 | 17 | public GDInvalidStateException(string message, Exception innerException) 18 | : base(message, innerException) 19 | { 20 | } 21 | 22 | protected GDInvalidStateException(SerializationInfo info, StreamingContext context) 23 | : base(info, context) 24 | { 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDSingleOperator.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDSingleOperator : GDSimpleSyntaxToken 4 | { 5 | public GDSingleOperatorType OperatorType { get; set; } 6 | 7 | internal override void HandleChar(char c, GDReadingState state) 8 | { 9 | state.Pop(); 10 | state.PassChar(c); 11 | } 12 | 13 | public override GDSyntaxToken Clone() 14 | { 15 | return new GDSingleOperator() 16 | { 17 | OperatorType = OperatorType 18 | }; 19 | } 20 | 21 | public override string ToString() 22 | { 23 | return OperatorType.Print(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SystemExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace System 4 | { 5 | internal static class SystemExtensionMethods 6 | { 7 | public static bool IsNullOrEmpty(this string self) => string.IsNullOrEmpty(self); 8 | public static bool IsNullOrWhiteSpace(this string self) => string.IsNullOrWhiteSpace(self); 9 | 10 | public static T PushAndPeek(this Stack self, T item) 11 | { 12 | self.Push(item); 13 | return item; 14 | } 15 | public static T PeekOrDefault(this Stack self) 16 | { 17 | if (self.Count == 0) 18 | return default; 19 | 20 | return self.Peek(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Resolvers/GDResolver.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | internal abstract class GDResolver : GDReader 4 | { 5 | public ITokenReceiver Owner { get; } 6 | 7 | public GDResolver(ITokenReceiver owner) 8 | { 9 | Owner = owner; 10 | } 11 | 12 | internal override void HandleSharpChar(GDReadingState state) 13 | { 14 | Owner.HandleReceivedToken(state.Push(new GDComment())); 15 | state.PassSharpChar(); 16 | } 17 | 18 | internal override void HandleLeftSlashChar(GDReadingState state) 19 | { 20 | Owner.HandleReceivedToken(state.Push(new GDMultiLineSplitToken())); 21 | state.PassLeftSlashChar(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/IGDClassDeclaration.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace GDShrapt.Reader 4 | { 5 | public interface IGDClassDeclaration : IGDNode 6 | { 7 | GDIdentifier Identifier { get; } 8 | GDClassMembersList Members { get; } 9 | GDTypeNode BaseType { get; } 10 | GDNode CreateEmptyInstance(); 11 | IEnumerable Variables { get; } 12 | IEnumerable Methods { get; } 13 | IEnumerable Enums { get; } 14 | IEnumerable InnerClasses { get; } 15 | IEnumerable IdentifiableMembers { get; } 16 | IEnumerable CustomAttributes { get; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/GDLiteralToken.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public abstract class GDLiteralToken : GDSimpleSyntaxToken 4 | { 5 | /// 6 | /// Throws ArgumentException if set invalid format value 7 | /// 8 | public abstract string Sequence { get; set; } 9 | 10 | public override int GetHashCode() 11 | { 12 | return Sequence?.GetHashCode() ?? base.GetHashCode(); 13 | } 14 | 15 | public abstract GDLiteralToken CloneWith(string stringValue); 16 | 17 | public override bool Equals(object obj) 18 | { 19 | if (obj is GDLiteralToken other) 20 | return string.Equals(Sequence, other.Sequence); 21 | return base.Equals(obj); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Resolvers/GDKeywordResolver.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | internal class GDKeywordResolver : GDSequenceResolver 4 | where KEYWORD : GDKeyword, new() 5 | { 6 | public new ITokenOrSkipReceiver Owner { get; } 7 | 8 | static KEYWORD _keyword = new KEYWORD(); 9 | 10 | public override string Sequence => _keyword.Sequence; 11 | 12 | public GDKeywordResolver(ITokenOrSkipReceiver owner) 13 | : base(owner) 14 | { 15 | Owner = owner; 16 | } 17 | 18 | protected override void OnMatch(GDReadingState state) 19 | { 20 | Owner.HandleReceivedToken(new KEYWORD()); 21 | } 22 | 23 | protected override void OnFail(GDReadingState state) 24 | { 25 | Owner.HandleReceivedTokenSkip(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Resolvers/GDSequenceTokenResolver.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | internal class GDSequenceTokenResolver : GDSequenceResolver 4 | where TOKEN : GDSequenceToken, new() 5 | { 6 | public new ITokenOrSkipReceiver Owner { get; } 7 | 8 | static TOKEN _token = new TOKEN(); 9 | 10 | public override string Sequence => _token.Sequence; 11 | 12 | public GDSequenceTokenResolver(ITokenOrSkipReceiver owner) 13 | : base(owner) 14 | { 15 | Owner = owner; 16 | } 17 | 18 | protected override void OnMatch(GDReadingState state) 19 | { 20 | Owner.HandleReceivedToken(new TOKEN()); 21 | } 22 | 23 | protected override void OnFail(GDReadingState state) 24 | { 25 | Owner.HandleReceivedTokenSkip(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDInvalidToken.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GDShrapt.Reader 4 | { 5 | public sealed class GDInvalidToken : GDCharSequence 6 | { 7 | readonly Predicate _stop; 8 | 9 | private GDInvalidToken() 10 | { 11 | } 12 | 13 | internal GDInvalidToken(Predicate stop) 14 | { 15 | _stop = stop; 16 | } 17 | 18 | internal GDInvalidToken(string sequence) 19 | { 20 | Sequence = sequence; 21 | } 22 | 23 | internal override bool CanAppendChar(char c, GDReadingState state) 24 | { 25 | return !_stop(c); 26 | } 27 | 28 | public override GDSyntaxToken Clone() 29 | { 30 | return new GDInvalidToken() 31 | { 32 | Sequence = Sequence 33 | }; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Resolvers/GDStartTrimmingResolver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GDShrapt.Reader 4 | { 5 | internal sealed class GDStartTrimmingResolver : GDResolver 6 | { 7 | private readonly Func _factory; 8 | new IIntendedTokenReceiver Owner { get; } 9 | public GDStartTrimmingResolver(IIntendedTokenReceiver owner, Func factory) 10 | : base(owner) 11 | { 12 | Owner = owner; 13 | _factory = factory; 14 | } 15 | 16 | 17 | internal override void HandleChar(char c, GDReadingState state) 18 | { 19 | if (Owner.ResolveSpaceToken(c, state)) 20 | return; 21 | 22 | state.Pop(); 23 | state.PushAndPass(_factory(), c); 24 | } 25 | 26 | internal override void HandleNewLineChar(GDReadingState state) 27 | { 28 | Owner.HandleReceivedToken(new GDNewLine()); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/GDSimpleSyntaxToken.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace GDShrapt.Reader 4 | { 5 | public abstract class GDSimpleSyntaxToken : GDSyntaxToken 6 | { 7 | public override void AppendTo(StringBuilder builder) 8 | { 9 | builder.Append(ToString()); 10 | } 11 | 12 | internal override void HandleNewLineChar(GDReadingState state) 13 | { 14 | state.Pop(); 15 | state.PassNewLine(); 16 | } 17 | 18 | internal override void HandleSharpChar(GDReadingState state) 19 | { 20 | state.Pop(); 21 | state.PassSharpChar(); 22 | } 23 | 24 | internal override void HandleLeftSlashChar(GDReadingState state) 25 | { 26 | state.Pop(); 27 | state.PassLeftSlashChar(); 28 | } 29 | 30 | public override int Length => ToString().Length; 31 | public override int NewLinesCount => 0; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Resolvers/GDElifResolver.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | internal class GDElifResolver : GDIntendedSequenceResolver 4 | { 5 | new IIntendedTokenReceiver Owner { get; } 6 | 7 | public override string Sequence => "elif"; 8 | 9 | public GDElifResolver(IIntendedTokenReceiver owner, int lineIntendation) 10 | : base(owner, lineIntendation, false) 11 | { 12 | Owner = owner; 13 | } 14 | 15 | protected override void OnFail(GDReadingState state) 16 | { 17 | // Ignore 18 | } 19 | 20 | protected override void OnMatch(GDReadingState state) 21 | { 22 | var branch = new GDElifBranch(CurrentResolvedIntendationInSpaces); 23 | 24 | branch.Add(new GDElifKeyword()); 25 | 26 | SendIntendationTokensToOwner(); 27 | Owner.HandleReceivedToken(branch); 28 | state.Push(branch); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/GDDualOperatorType.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public enum GDDualOperatorType 4 | { 5 | Null = 0, 6 | MoreThan, 7 | LessThan, 8 | Assignment, 9 | Subtraction, 10 | Division, 11 | Multiply, 12 | Addition, 13 | AddAndAssign, 14 | NotEqual, 15 | MultiplyAndAssign, 16 | SubtractAndAssign, 17 | LessThanOrEqual, 18 | MoreThanOrEqual, 19 | Equal, 20 | DivideAndAssign, 21 | Or, 22 | Or2, 23 | And, 24 | And2, 25 | Is, 26 | As, 27 | ModAndAssign, 28 | BitShiftLeft, 29 | BitShiftRight, 30 | Mod, 31 | Xor, 32 | BitwiseOr, 33 | BitwiseAnd, 34 | In, 35 | BitwiseAndAndAssign, 36 | BitwiseOrAndAssign, 37 | Power, 38 | PowerAndAssign, 39 | BitShiftLeftAndAssign, 40 | BitShiftRightAndAssign, 41 | XorAndAssign 42 | } 43 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Lists/GDIntendedTokensList.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public abstract class GDIntendedTokensList : GDSeparatedList, 4 | IIntendedTokenReceiver 5 | where TOKEN : GDSyntaxToken 6 | { 7 | protected int LineIntendationThreshold { get; } 8 | 9 | internal GDIntendedTokensList(int lineIntendation) 10 | { 11 | LineIntendationThreshold = lineIntendation; 12 | } 13 | 14 | public GDIntendedTokensList() 15 | { 16 | 17 | } 18 | 19 | void IIntendedTokenReceiver.HandleReceivedToken(GDIntendation token) 20 | { 21 | ListForm.AddToEnd(token); 22 | } 23 | 24 | void INewLineReceiver.HandleReceivedToken(GDNewLine token) 25 | { 26 | ListForm.AddToEnd(token); 27 | } 28 | 29 | void ITokenReceiver.HandleReceivedToken(TOKEN token) 30 | { 31 | ListForm.AddToEnd(token); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/GDSequenceToken.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public abstract class GDSequenceToken : GDSimpleSyntaxToken 4 | { 5 | public abstract string Sequence { get; } 6 | 7 | internal override void HandleChar(char c, GDReadingState state) 8 | { 9 | state.Pop(); 10 | state.PassChar(c); 11 | } 12 | 13 | internal override void HandleNewLineChar(GDReadingState state) 14 | { 15 | state.Pop(); 16 | state.PassNewLine(); 17 | } 18 | 19 | internal override void HandleSharpChar(GDReadingState state) 20 | { 21 | state.Pop(); 22 | state.PassChar('#'); 23 | } 24 | 25 | internal override void HandleLeftSlashChar(GDReadingState state) 26 | { 27 | state.Pop(); 28 | state.PassLeftSlashChar(); 29 | } 30 | 31 | public override string ToString() 32 | { 33 | return Sequence; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Resolvers/GDElseResolver.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | internal sealed class GDElseResolver : GDIntendedSequenceResolver 4 | { 5 | new IIntendedTokenOrSkipReceiver Owner { get; } 6 | 7 | public override string Sequence => "else"; 8 | 9 | public GDElseResolver(IIntendedTokenOrSkipReceiver owner, int lineIntendation) 10 | : base(owner, lineIntendation) 11 | { 12 | Owner = owner; 13 | } 14 | 15 | protected override void OnFail(GDReadingState state) 16 | { 17 | Owner.HandleReceivedTokenSkip(); 18 | } 19 | 20 | protected override void OnMatch(GDReadingState state) 21 | { 22 | var branch = new GDElseBranch(CurrentResolvedIntendationInSpaces); 23 | 24 | branch.Add(new GDElseKeyword()); 25 | 26 | SendIntendationTokensToOwner(); 27 | Owner.HandleReceivedToken(branch); 28 | state.Push(branch); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDSpace.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GDShrapt.Reader 4 | { 5 | public sealed class GDSpace : GDCharSequence 6 | { 7 | public new string Sequence 8 | { 9 | get => base.Sequence; 10 | set 11 | { 12 | if (!string.IsNullOrWhiteSpace(value)) 13 | throw new FormatException("Invalid space format."); 14 | base.Sequence = value; 15 | } 16 | } 17 | 18 | internal override bool CanAppendChar(char c, GDReadingState state) 19 | { 20 | return IsSpace(c); 21 | } 22 | 23 | public static GDSpace operator +(GDSpace one, GDSpace other) 24 | { 25 | one.Sequence += other.Sequence; 26 | return one; 27 | } 28 | 29 | public override GDSyntaxToken Clone() 30 | { 31 | return new GDSpace() 32 | { 33 | Sequence = Sequence 34 | }; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/GDSingleCharToken.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public abstract class GDSingleCharToken : GDSimpleSyntaxToken 4 | { 5 | public abstract char Char { get; } 6 | 7 | internal override void HandleChar(char c, GDReadingState state) 8 | { 9 | if (Char != c) 10 | throw new GDInvalidStateException(); 11 | 12 | state.Pop(); 13 | } 14 | 15 | internal override void HandleNewLineChar(GDReadingState state) 16 | { 17 | if (Char != '\n') 18 | throw new GDInvalidStateException(); 19 | 20 | state.Pop(); 21 | } 22 | 23 | internal override void HandleSharpChar(GDReadingState state) 24 | { 25 | if (Char != '#') 26 | throw new GDInvalidStateException(); 27 | 28 | throw new GDInvalidStateException(); 29 | } 30 | 31 | public override string ToString() 32 | { 33 | return Char.ToString(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Resolvers/GDSingleCharTokenResolver.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | internal class GDSingleCharTokenResolver : GDResolver 4 | where TOKEN : GDSingleCharToken, new() 5 | { 6 | public new ITokenOrSkipReceiver Owner { get; } 7 | 8 | static TOKEN _token = new TOKEN(); 9 | 10 | public GDSingleCharTokenResolver(ITokenOrSkipReceiver owner) 11 | : base(owner) 12 | { 13 | Owner = owner; 14 | } 15 | 16 | internal override void HandleChar(char c, GDReadingState state) 17 | { 18 | state.Pop(); 19 | 20 | if (_token.Char == c) 21 | { 22 | Owner.HandleReceivedToken(new TOKEN()); 23 | return; 24 | } 25 | 26 | Owner.HandleReceivedTokenSkip(); 27 | state.PassChar(c); 28 | } 29 | 30 | internal override void HandleNewLineChar(GDReadingState state) 31 | { 32 | HandleChar('\n', state); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/GDReadSettings.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public class GDReadSettings 4 | { 5 | /// 6 | /// Amount of spaces that equals a single tabulation 7 | /// Default value is 4 8 | /// 9 | public int SingleTabSpacesCost { get; set; } = 4; 10 | 11 | public int ReadBufferSize { get; set; } = 1024; 12 | 13 | /// 14 | /// If the reading state exceeds this value a StackOverflowException will be thrown. 15 | /// Set null and you will gain a real stackoverflow exception with unpredictable behavior. 16 | /// 17 | public int? MaxReadingStack { get; set; } = 64; 18 | 19 | /// 20 | /// If the stactrace exceeds this value a StackOverflowException will be thrown. 21 | /// Set null and you will gain a real stackoverflow exception with unpredictable behavior. 22 | /// Use it only for debugging 23 | /// 24 | public int? MaxStacktraceFramesCount { get; set; } = 512; 25 | } 26 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Semenov Dmitry 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Lists/GDEnumValuesList.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDEnumValuesList : GDCommaSeparatedList, 4 | ITokenReceiver 5 | { 6 | internal override GDReader ResolveNode() 7 | { 8 | var node = new GDEnumValueDeclaration(); 9 | ListForm.AddToEnd(node); 10 | return node; 11 | } 12 | 13 | internal override bool IsStopChar(char c) 14 | { 15 | return !c.IsIdentifierStartChar(); 16 | } 17 | 18 | public override GDNode CreateEmptyInstance() 19 | { 20 | return new GDEnumValuesList(); 21 | } 22 | 23 | internal override void Visit(IGDVisitor visitor) 24 | { 25 | visitor.Visit(this); 26 | } 27 | 28 | internal override void Left(IGDVisitor visitor) 29 | { 30 | visitor.Left(this); 31 | } 32 | 33 | void ITokenReceiver.HandleReceivedToken(GDEnumValueDeclaration token) 34 | { 35 | ListForm.AddToEnd(token); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Lists/GDParametersList.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDParametersList : GDCommaSeparatedList, 4 | ITokenReceiver 5 | { 6 | internal override bool IsStopChar(char c) 7 | { 8 | return !c.IsIdentifierStartChar(); 9 | } 10 | 11 | internal override GDReader ResolveNode() 12 | { 13 | var node = new GDParameterDeclaration(); 14 | ListForm.AddToEnd(node); 15 | return node; 16 | } 17 | 18 | public override GDNode CreateEmptyInstance() 19 | { 20 | return new GDParametersList(); 21 | } 22 | 23 | internal override void Visit(IGDVisitor visitor) 24 | { 25 | visitor.Visit(this); 26 | } 27 | 28 | internal override void Left(IGDVisitor visitor) 29 | { 30 | visitor.Left(this); 31 | } 32 | 33 | void ITokenReceiver.HandleReceivedToken(GDParameterDeclaration token) 34 | { 35 | ListForm.AddToEnd(token); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDPathSpecifier.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GDShrapt.Reader 4 | { 5 | public class GDPathSpecifier : GDSequenceToken 6 | { 7 | public string IdentifierValue { get; set; } 8 | public GDPathSpecifierType Type { get; set; } 9 | 10 | public override string Sequence 11 | { 12 | get 13 | { 14 | switch (Type) 15 | { 16 | case GDPathSpecifierType.Current: 17 | return "."; 18 | case GDPathSpecifierType.Parent: 19 | return ".."; 20 | case GDPathSpecifierType.Identifier: 21 | return IdentifierValue; 22 | default: 23 | throw new NotSupportedException(Type.ToString()); 24 | } 25 | } 26 | } 27 | 28 | public override GDSyntaxToken Clone() 29 | { 30 | return new GDPathSpecifier() 31 | { 32 | Type = Type, 33 | IdentifierValue = IdentifierValue 34 | }; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader.Tests/Scripts/Sample5.gd: -------------------------------------------------------------------------------- 1 | extends PanelContainer 2 | class_name InventorySlot 3 | 4 | 5 | @export var type: InventoryItem.Type 6 | 7 | 8 | # Custom init function so that it doesn't error 9 | func init(t: InventoryItem.Type, cms: Vector2) -> void: 10 | type = t 11 | custom_minimum_size = cms 12 | 13 | 14 | # _at_position is not used because it doesn't matter where on the panel 15 | # the item is dropped 16 | func _can_drop_data(_at_position: Vector2, data: Variant) -> bool: 17 | if data is InventoryItem: 18 | #This is the text that displays uupon pulling an item out. 19 | %summary.text =( str("atk:" + str(data.physicalattack) +'\n' + data.lore)) 20 | if type == InventoryItem.Type.MAIN: 21 | if get_child_count() == 0: 22 | return true 23 | else: 24 | # Swap two items 25 | return get_child(0).type == data.type 26 | else: 27 | return data.type == type 28 | 29 | 30 | return false 31 | 32 | 33 | # _at_position is not used because it doesn't matter where on the panel 34 | # the item is dropped 35 | func _drop_data(_at_position: Vector2, data: Variant) -> void: 36 | if get_child_count() > 0: 37 | var item := get_child(0) 38 | if item == data: return 39 | remove_child(item) 40 | data.get_parent().add_child(item) 41 | data.get_parent().remove_child(data) 42 | add_child(data) 43 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDComment.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDComment : GDCharSequence 4 | { 5 | public new string Sequence 6 | { 7 | get => base.Sequence; 8 | set => base.Sequence = (value?.StartsWith("#") ?? true) ? value : "#" + value; 9 | } 10 | 11 | public GDComment() 12 | { 13 | } 14 | 15 | internal override void HandleNewLineChar(GDReadingState state) 16 | { 17 | CompleteSequence(state); 18 | state.PassNewLine(); 19 | } 20 | 21 | internal override bool CanAppendChar(char c, GDReadingState state) 22 | { 23 | return true; 24 | } 25 | 26 | internal override void HandleSharpChar(GDReadingState state) 27 | { 28 | HandleChar('#', state); 29 | } 30 | 31 | internal override void HandleLeftSlashChar(GDReadingState state) 32 | { 33 | HandleChar('\\', state); 34 | } 35 | 36 | public override GDSyntaxToken Clone() 37 | { 38 | return new GDComment() 39 | { 40 | Sequence = Sequence 41 | }; 42 | } 43 | 44 | public override string ToString() 45 | { 46 | return $"{Sequence}"; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/GDTokensContainer.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | /// 4 | /// Special container for code manipulation 5 | /// 6 | public sealed class GDTokensContainer : GDNode 7 | { 8 | public GDTokensListForm ListForm { get; } 9 | public override GDTokensForm Form => ListForm; 10 | 11 | public GDTokensContainer(params GDSyntaxToken[] tokens) 12 | { 13 | ListForm = new GDTokensListForm(this); 14 | 15 | for (int i = 0; i < tokens.Length; i++) 16 | ListForm.AddToEnd(tokens[i]); 17 | } 18 | 19 | public override GDNode CreateEmptyInstance() 20 | { 21 | return new GDTokensContainer(); 22 | } 23 | 24 | internal override void Visit(IGDVisitor visitor) 25 | { 26 | // visitor.Visit(this); 27 | } 28 | 29 | internal override void Left(IGDVisitor visitor) 30 | { 31 | // visitor.Left(this); 32 | } 33 | 34 | internal override void HandleChar(char c, GDReadingState state) 35 | { 36 | throw new GDInvalidStateException(); 37 | } 38 | 39 | internal override void HandleNewLineChar(GDReadingState state) 40 | { 41 | throw new GDInvalidStateException(); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader.Tests/GDShrapt.Reader.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | PreserveNewest 24 | 25 | 26 | PreserveNewest 27 | 28 | 29 | PreserveNewest 30 | 31 | 32 | PreserveNewest 33 | 34 | 35 | PreserveNewest 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Lists/GDExpressionsList.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDExpressionsList : GDCommaSeparatedList, 4 | ITokenOrSkipReceiver 5 | { 6 | readonly int _intendation; 7 | 8 | internal GDExpressionsList(int intendation) 9 | { 10 | _intendation = intendation; 11 | } 12 | 13 | public GDExpressionsList() 14 | { 15 | } 16 | 17 | internal override GDReader ResolveNode() 18 | { 19 | return new GDExpressionResolver(this, _intendation); 20 | } 21 | 22 | internal override bool IsStopChar(char c) 23 | { 24 | return c.IsExpressionStopChar(); 25 | } 26 | 27 | public override GDNode CreateEmptyInstance() 28 | { 29 | return new GDExpressionsList(); 30 | } 31 | 32 | internal override void Visit(IGDVisitor visitor) 33 | { 34 | visitor.Visit(this); 35 | } 36 | 37 | internal override void Left(IGDVisitor visitor) 38 | { 39 | visitor.Left(this); 40 | } 41 | 42 | void ITokenReceiver.HandleReceivedToken(GDExpression token) 43 | { 44 | ListForm.AddToEnd(token); 45 | } 46 | 47 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 48 | { 49 | SetAsCompleted(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Walking/GDBaseVisitor.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | 4 | namespace GDShrapt.Reader 5 | { 6 | public abstract class GDBaseVisitor : IGDBaseVisitor 7 | { 8 | Stack _nodesStack = new Stack(); 9 | 10 | public IReadOnlyCollection NodesStack { get; } 11 | 12 | public GDNode Current => _nodesStack.Count > 0 ? _nodesStack.Peek() : default; 13 | 14 | public GDBaseVisitor() 15 | { 16 | NodesStack = new ReadOnlyStack(_nodesStack); 17 | } 18 | 19 | public virtual void EnterNode(GDNode node) 20 | { 21 | _nodesStack.Push(node); 22 | } 23 | 24 | public virtual void LeftNode() 25 | { 26 | _nodesStack.Pop(); 27 | } 28 | 29 | private class ReadOnlyStack : IReadOnlyCollection 30 | { 31 | private Stack _nodesStack; 32 | 33 | public ReadOnlyStack(Stack nodesStack) 34 | { 35 | _nodesStack = nodesStack; 36 | } 37 | 38 | public int Count => _nodesStack.Count; 39 | 40 | public IEnumerator GetEnumerator() 41 | { 42 | return _nodesStack.GetEnumerator(); 43 | } 44 | 45 | IEnumerator IEnumerable.GetEnumerator() 46 | { 47 | return GetEnumerator(); 48 | } 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDMultiLineSplitToken.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | namespace GDShrapt.Reader 4 | { 5 | public sealed class GDMultiLineSplitToken : GDCharSequence 6 | { 7 | bool _facedNewLineToken; 8 | 9 | public override GDSyntaxToken Clone() 10 | { 11 | return new GDMultiLineSplitToken() 12 | { 13 | Sequence = Sequence 14 | }; 15 | } 16 | 17 | internal override void HandleLeftSlashChar(GDReadingState state) 18 | { 19 | base.HandleChar('\\', state); 20 | } 21 | 22 | internal override void HandleChar(char c, GDReadingState state) 23 | { 24 | base.HandleChar(c, state); 25 | } 26 | 27 | internal override void HandleNewLineChar(GDReadingState state) 28 | { 29 | base.HandleChar('\n', state); 30 | } 31 | 32 | internal override void HandleSharpChar(GDReadingState state) 33 | { 34 | base.HandleChar('#', state); 35 | } 36 | 37 | public override int NewLinesCount => Sequence?.Count(x => x == '\n') ?? 0; 38 | 39 | internal override bool CanAppendChar(char c, GDReadingState state) 40 | { 41 | if (_facedNewLineToken) 42 | return false; 43 | 44 | if (c.IsNewLine()) 45 | { 46 | _facedNewLineToken = true; 47 | return true; 48 | } 49 | 50 | return true; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/GDShrapt.Reader.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | true 6 | 4.4.0-alpha 7 | elamaunt 8 | GDShrapt 9 | GDShrapt.Reader is .Net library and object-oriented one-pass parser of GDScript. It can build a lexical tree of GDScript code or generate a new code from scratch. 10 | Is free to use. 11 | 12 | Usage: Just create a GDScriptReader instance and call methods from it. 13 | LICENSE 14 | 15 | elamaunt 16 | https://github.com/elamaunt/GDShrapt 17 | git 18 | GDShrapt GDScript reader parser codegeneration Godot lexical analyzer 19 | 4.4.0 20 | 4.4.0 21 | true 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | True 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Lists/GDElifBranchesList.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDElifBranchesList : GDIntendedTokensList 4 | { 5 | bool _completed; 6 | 7 | internal GDElifBranchesList(int lineIntendation) 8 | : base (lineIntendation) 9 | { 10 | } 11 | 12 | public GDElifBranchesList() 13 | { 14 | 15 | } 16 | 17 | internal override void HandleChar(char c, GDReadingState state) 18 | { 19 | if (!_completed) 20 | { 21 | _completed = true; 22 | state.PushAndPass(new GDElifResolver(this, LineIntendationThreshold), c); 23 | return; 24 | } 25 | 26 | state.PopAndPass(c); 27 | } 28 | 29 | internal override void HandleNewLineChar(GDReadingState state) 30 | { 31 | if (!_completed) 32 | { 33 | _completed = true; 34 | state.Push(new GDElifResolver(this, LineIntendationThreshold)); 35 | state.PassNewLine(); 36 | return; 37 | } 38 | 39 | state.PopAndPassNewLine(); 40 | } 41 | 42 | public override GDNode CreateEmptyInstance() 43 | { 44 | return new GDElifBranchesList(); 45 | } 46 | 47 | internal override void Visit(IGDVisitor visitor) 48 | { 49 | visitor.Visit(this); 50 | } 51 | 52 | internal override void Left(IGDVisitor visitor) 53 | { 54 | visitor.Left(this); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Lists/GDDictionaryKeyValueDeclarationList.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDDictionaryKeyValueDeclarationList : GDCommaSeparatedList, 4 | ITokenOrSkipReceiver 5 | { 6 | readonly int _intendation; 7 | 8 | internal GDDictionaryKeyValueDeclarationList(int intendation) 9 | { 10 | _intendation = intendation; 11 | } 12 | 13 | public GDDictionaryKeyValueDeclarationList() 14 | { 15 | } 16 | 17 | internal override GDReader ResolveNode() 18 | { 19 | return new GDDictionaryKeyValueResolver(this, this, _intendation); 20 | } 21 | 22 | internal override bool IsStopChar(char c) 23 | { 24 | return c == '}'; 25 | } 26 | 27 | public override GDNode CreateEmptyInstance() 28 | { 29 | return new GDDictionaryKeyValueDeclarationList(); 30 | } 31 | 32 | internal override void Visit(IGDVisitor visitor) 33 | { 34 | visitor.Visit(this); 35 | } 36 | 37 | internal override void Left(IGDVisitor visitor) 38 | { 39 | visitor.Left(this); 40 | } 41 | 42 | void ITokenReceiver.HandleReceivedToken(GDDictionaryKeyValueDeclaration token) 43 | { 44 | ListForm.AddToEnd(token); 45 | } 46 | 47 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 48 | { 49 | SetAsCompleted(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Lists/GDMatchCasesList.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDMatchCasesList : GDIntendedTokensList 4 | { 5 | private int _lineIntendationThreshold; 6 | bool _completed; 7 | 8 | internal GDMatchCasesList(int lineIntendation) 9 | { 10 | _lineIntendationThreshold = lineIntendation; 11 | } 12 | 13 | public GDMatchCasesList() 14 | { 15 | } 16 | 17 | internal override void HandleChar(char c, GDReadingState state) 18 | { 19 | if (!_completed) 20 | { 21 | _completed = true; 22 | state.PushAndPass(new GDMatchCasesResolver(this, _lineIntendationThreshold), c); 23 | return; 24 | } 25 | 26 | state.PopAndPass(c); 27 | } 28 | 29 | internal override void HandleNewLineChar(GDReadingState state) 30 | { 31 | if (!_completed) 32 | { 33 | _completed = true; 34 | state.PushAndPassNewLine(new GDMatchCasesResolver(this, _lineIntendationThreshold)); 35 | return; 36 | } 37 | 38 | state.PopAndPassNewLine(); 39 | } 40 | 41 | public override GDNode CreateEmptyInstance() 42 | { 43 | return new GDMatchCasesList(); 44 | } 45 | 46 | internal override void Visit(IGDVisitor visitor) 47 | { 48 | visitor.Visit(this); 49 | } 50 | 51 | internal override void Left(IGDVisitor visitor) 52 | { 53 | visitor.Left(this); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader.Tests/Scripts/Sample3.gd: -------------------------------------------------------------------------------- 1 | extends Label 2 | # Displays some useful debug information in a Label. 3 | 4 | @onready var player = $"../Player" 5 | @onready var voxel_world = $"../VoxelWorld" 6 | 7 | 8 | func _process(_delta): 9 | if Input.is_action_just_pressed("debug"): 10 | visible = not visible 11 | 12 | text = "Position: " + _vector_to_string_appropriate_digits(player.transform.origin) 13 | text += "\nEffective render distance: " + str(voxel_world.effective_render_distance) 14 | text += "\nLooking: " + _cardinal_string_from_radians(player.transform.basis.get_euler().y) 15 | text += "\nMemory: " + "%3.0f" % (OS.get_static_memory_usage() / 1048576.0) + " MiB" 16 | text += "\nFPS: " + str(Engine.get_frames_per_second()) 17 | 18 | 19 | # Avoids the problem of showing more digits than needed or available. 20 | func _vector_to_string_appropriate_digits(vector): 21 | var factors = [1000, 1000, 1000] 22 | for i in range(3): 23 | if abs(vector[i]) > 4096: 24 | factors[i] = factors[i] / 10 25 | if abs(vector[i]) > 65536: 26 | factors[i] = factors[i] / 10 27 | if abs(vector[i]) > 524288: 28 | factors[i] = factors[i] / 10 29 | 30 | return "(" + \ 31 | str(round(vector.x * factors[0]) / factors[0]) + ", " + \ 32 | str(round(vector.y * factors[1]) / factors[1]) + ", " + \ 33 | str(round(vector.z * factors[2]) / factors[2]) + ")" 34 | 35 | 36 | # Expects a rotation where 0 is North, on the range -PI to PI. 37 | func _cardinal_string_from_radians(angle): 38 | if angle > TAU * 3 / 8: 39 | return "South" 40 | if angle < -TAU * 3 / 8: 41 | return "South" 42 | if angle > TAU * 1 / 8: 43 | return "West" 44 | if angle < -TAU * 1 / 8: 45 | return "East" 46 | return "North" 47 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Resolvers/GDStringNodeResolver.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | internal class GDStringNodeResolver : GDPatternResolver 4 | { 5 | new ITokenOrSkipReceiver Owner { get; } 6 | 7 | public GDStringNodeResolver(ITokenOrSkipReceiver owner) 8 | : base(owner) 9 | { 10 | Owner = owner; 11 | } 12 | 13 | public override string[] GeneratePatterns() 14 | { 15 | return new string[] 16 | { 17 | "\"", 18 | "'", 19 | "\"\"\"", 20 | "'''", 21 | }; 22 | } 23 | 24 | protected override void PatternMatched(string pattern, GDReadingState state) 25 | { 26 | switch (pattern) 27 | { 28 | case "\"": 29 | Owner.HandleReceivedToken(state.Push(new GDDoubleQuotasStringNode())); 30 | break; 31 | case "'": 32 | Owner.HandleReceivedToken(state.Push(new GDSingleQuotasStringNode())); 33 | break; 34 | case "\"\"\"": 35 | Owner.HandleReceivedToken(state.Push(new GDTripleDoubleQuotasStringNode())); 36 | break; 37 | case "'''": 38 | Owner.HandleReceivedToken(state.Push(new GDTripleSingleQuotasStringNode())); 39 | break; 40 | default: 41 | Owner.HandleReceivedTokenSkip(); 42 | break; 43 | } 44 | 45 | if (pattern != null) 46 | state.PassString(pattern); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/GDShrapt.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.8.34309.116 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GDShrapt.Reader.Tests", "GDShrapt.Reader.Tests\GDShrapt.Reader.Tests.csproj", "{2A9E4095-E028-474B-A4A6-9E928AE9ADFE}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GDShrapt.Reader", "GDShrapt.Reader\GDShrapt.Reader.csproj", "{EF8F42CC-A17C-4F08-800D-04BC5EAB59F9}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {2A9E4095-E028-474B-A4A6-9E928AE9ADFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {2A9E4095-E028-474B-A4A6-9E928AE9ADFE}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {2A9E4095-E028-474B-A4A6-9E928AE9ADFE}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {2A9E4095-E028-474B-A4A6-9E928AE9ADFE}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {EF8F42CC-A17C-4F08-800D-04BC5EAB59F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {EF8F42CC-A17C-4F08-800D-04BC5EAB59F9}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {EF8F42CC-A17C-4F08-800D-04BC5EAB59F9}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {EF8F42CC-A17C-4F08-800D-04BC5EAB59F9}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {665B514F-FCDB-4D8A-8B4A-EFFFB6CA51D3} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Lists/GDClassMembersList.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDClassMembersList : GDIntendedTokensList, 4 | IIntendedTokenReceiver 5 | { 6 | bool _completed; 7 | 8 | internal GDClassMembersList(int lineIntendation) 9 | : base(lineIntendation) 10 | { 11 | } 12 | 13 | public GDClassMembersList() 14 | { 15 | } 16 | 17 | internal override void HandleChar(char c, GDReadingState state) 18 | { 19 | if (!_completed) 20 | { 21 | _completed = true; 22 | state.PushAndPass(new GDClassMembersResolver(this, LineIntendationThreshold), c); 23 | return; 24 | } 25 | 26 | state.PopAndPass(c); 27 | } 28 | 29 | internal override void HandleNewLineChar(GDReadingState state) 30 | { 31 | if (!_completed) 32 | { 33 | _completed = true; 34 | state.Push(new GDClassMembersResolver(this, LineIntendationThreshold)); 35 | state.PassNewLine(); 36 | return; 37 | } 38 | 39 | state.PopAndPassNewLine(); 40 | } 41 | 42 | public override GDNode CreateEmptyInstance() 43 | { 44 | return new GDClassMembersList(); 45 | } 46 | 47 | internal override void Visit(IGDVisitor visitor) 48 | { 49 | visitor.Visit(this); 50 | } 51 | 52 | internal override void Left(IGDVisitor visitor) 53 | { 54 | visitor.Left(this); 55 | } 56 | 57 | void ITokenReceiver.HandleReceivedToken(GDClassMember token) 58 | { 59 | ListForm.AddToEnd(token); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader.Tests/AssertHelper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using System.Linq; 3 | using System.Text; 4 | 5 | namespace GDShrapt.Reader.Tests 6 | { 7 | public static class AssertHelper 8 | { 9 | internal static void CompareCodeStrings(string s1, string s2) 10 | { 11 | s1 = s1.Replace("\r\n", "\n").Replace(" ", "\t"); 12 | s2 = s2.Replace("\r\n", "\n").Replace(" ", "\t"); 13 | 14 | #if DEBUG 15 | bool diffFound = false; 16 | var original = new StringBuilder(); 17 | var other = new StringBuilder(); 18 | 19 | if (s1.Length == s2.Length) 20 | { 21 | for (int i = 0; i < s1.Length; i++) 22 | { 23 | var ch1 = s1[i]; 24 | var ch2 = s2[i]; 25 | 26 | if (ch1 != ch2) 27 | diffFound = true; 28 | 29 | if (diffFound) 30 | { 31 | original.Append(ch1); 32 | other.Append(ch2); 33 | } 34 | } 35 | } 36 | #endif 37 | 38 | Assert.AreEqual(s1, s2, "The code strings are not same"); 39 | } 40 | 41 | internal static void NoInvalidTokens(GDNode node) 42 | { 43 | var invalidTokens = node.AllInvalidTokens.ToArray(); 44 | var messageBuilder = new StringBuilder(); 45 | 46 | messageBuilder.AppendLine(); 47 | for (int i = 0; i < invalidTokens.Length; i++) 48 | { 49 | var token = invalidTokens[i]; 50 | messageBuilder.AppendLine($"{token.StartLine}.{token.StartColumn}: " + token); 51 | } 52 | 53 | Assert.AreEqual(0, invalidTokens.Length, messageBuilder.ToString(), "There are invalid tokens in the code"); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Lists/GDCommaSeparatedList.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public abstract class GDCommaSeparatedList : GDSeparatedList, 4 | ITokenReceiver, 5 | INewLineReceiver, 6 | ITokenReceiver 7 | where NODE : GDSyntaxToken 8 | { 9 | bool _completed; 10 | 11 | internal abstract GDReader ResolveNode(); 12 | internal abstract bool IsStopChar(char c); 13 | 14 | internal override void HandleChar(char c, GDReadingState state) 15 | { 16 | if (IsSpace(c)) 17 | { 18 | ListForm.AddToEnd(state.Push(new GDSpace())); 19 | state.PassChar(c); 20 | return; 21 | } 22 | 23 | if (c == ',') 24 | { 25 | ListForm.AddToEnd(new GDComma()); 26 | return; 27 | } 28 | else 29 | { 30 | if (!_completed && !IsStopChar(c)) 31 | { 32 | state.PushAndPass(ResolveNode(), c); 33 | return; 34 | } 35 | } 36 | 37 | state.PopAndPass(c); 38 | } 39 | 40 | internal override void HandleNewLineChar(GDReadingState state) 41 | { 42 | ListForm.AddToEnd(new GDNewLine()); 43 | } 44 | 45 | internal void SetAsCompleted() 46 | { 47 | _completed = true; 48 | } 49 | 50 | void INewLineReceiver.HandleReceivedToken(GDNewLine token) 51 | { 52 | ListForm.AddToEnd(token); 53 | } 54 | 55 | void ITokenReceiver.HandleReceivedToken(GDNewLine token) 56 | { 57 | ListForm.AddToEnd(token); 58 | } 59 | 60 | void ITokenReceiver.HandleReceivedToken(GDComma token) 61 | { 62 | ListForm.AddToEnd(token); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/GDReceiver.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace GDShrapt.Reader 4 | { 5 | internal class GDReceiver : 6 | IIntendedTokenReceiver, 7 | ITokenOrSkipReceiver, 8 | IIntendedTokenReceiver, 9 | ITokenOrSkipReceiver 10 | { 11 | public List Tokens { get; } = new List(); 12 | 13 | public void HandleReceivedToken(GDStatement token) 14 | { 15 | Tokens.Add(token); 16 | } 17 | 18 | public void HandleReceivedToken(GDComment token) 19 | { 20 | Tokens.Add(token); 21 | } 22 | 23 | public void HandleReceivedToken(GDAttribute token) 24 | { 25 | Tokens.Add(token); 26 | } 27 | 28 | public void HandleReceivedToken(GDNewLine token) 29 | { 30 | Tokens.Add(token); 31 | } 32 | 33 | public void HandleReceivedToken(GDSpace token) 34 | { 35 | Tokens.Add(token); 36 | } 37 | 38 | public void HandleReceivedToken(GDInvalidToken token) 39 | { 40 | Tokens.Add(token); 41 | } 42 | 43 | public void HandleReceivedToken(GDExpression token) 44 | { 45 | Tokens.Add(token); 46 | } 47 | 48 | public void HandleReceivedToken(GDIntendation token) 49 | { 50 | Tokens.Add(token); 51 | } 52 | 53 | public void HandleReceivedToken(GDNode token) 54 | { 55 | Tokens.Add(token); 56 | } 57 | 58 | public void HandleReceivedToken(GDTypeNode token) 59 | { 60 | Tokens.Add(token); 61 | } 62 | 63 | public void HandleReceivedToken(GDMultiLineSplitToken token) 64 | { 65 | Tokens.Add(token); 66 | } 67 | 68 | public void HandleReceivedTokenSkip() 69 | { 70 | 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Resolvers/GDSingleOperatorResolver.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | internal class GDSingleOperatorResolver : GDPatternResolver 4 | { 5 | public new ITokenOrSkipReceiver Owner { get; } 6 | public GDSingleOperatorResolver(ITokenOrSkipReceiver owner) 7 | : base(owner) 8 | { 9 | Owner = owner; 10 | } 11 | 12 | public override string[] GeneratePatterns() 13 | { 14 | return new string[] 15 | { 16 | "not", 17 | "-", 18 | "!", 19 | "~" 20 | }; 21 | } 22 | 23 | protected override void PatternMatched(string pattern, GDReadingState state) 24 | { 25 | switch (pattern) 26 | { 27 | case "!": 28 | case "not": 29 | Append(GDSingleOperatorType.Not); 30 | break; 31 | case "-": 32 | Append(GDSingleOperatorType.Negate); 33 | break; 34 | case "~": 35 | Append(GDSingleOperatorType.BitwiseNegate); 36 | break; 37 | default: 38 | Owner.HandleReceivedTokenSkip(); 39 | 40 | if (pattern != null) 41 | { 42 | for (int i = 0; i < pattern.Length; i++) 43 | state.PassChar(pattern[i]); 44 | } 45 | break; 46 | } 47 | } 48 | 49 | void Append(GDSingleOperatorType operatorType) 50 | { 51 | Owner.HandleReceivedToken(new GDSingleOperator() { OperatorType = operatorType }); 52 | } 53 | 54 | internal override void ForceComplete(GDReadingState state) 55 | { 56 | Owner.HandleReceivedTokenSkip(); 57 | base.ForceComplete(state); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader.Tests/InvalidTokenTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System.Linq; 4 | 5 | namespace GDShrapt.Reader.Tests 6 | { 7 | [TestClass] 8 | public class InvalidTokenTests 9 | { 10 | [TestMethod] 11 | public void InvalidStaticTest() 12 | { 13 | var reader = new GDScriptReader(); 14 | 15 | var code = @"static signal my_signal(value, other_value)"; 16 | 17 | var declaration = reader.ParseFileContent(code); 18 | Assert.IsNotNull(declaration); 19 | 20 | Assert.AreEqual(1, declaration.AllInvalidTokens.Count()); 21 | Assert.AreEqual("static", declaration.AllInvalidTokens.First().Sequence); 22 | AssertHelper.CompareCodeStrings(code, declaration.ToString()); 23 | } 24 | 25 | [TestMethod] 26 | public void DoubleStaticTest() 27 | { 28 | var reader = new GDScriptReader(); 29 | 30 | var code = @"static static func my_method(value): return value > 0"; 31 | 32 | var declaration = reader.ParseFileContent(code); 33 | Assert.IsNotNull(declaration); 34 | 35 | Assert.AreEqual(1, declaration.AllInvalidTokens.Count()); 36 | Assert.AreEqual("static", declaration.AllInvalidTokens.First().Sequence); 37 | AssertHelper.CompareCodeStrings(code, declaration.ToString()); 38 | } 39 | 40 | [TestMethod] 41 | public void InvalidClassNameTest() 42 | { 43 | var reader = new GDScriptReader(); 44 | 45 | var code = @"tool 46 | class_name 123H+=Ter^5r3_-ain-DataSaver 47 | extends ResourceFormatSaver 48 | "; 49 | 50 | var @class = reader.ParseFileContent(code); 51 | Assert.IsNotNull(@class); 52 | 53 | @class.AllInvalidTokens.Select(x => x.ToString()).Should().BeEquivalentTo(new string[] 54 | { 55 | "123", 56 | "H+=Ter^5r3_-ain-DataSaver" 57 | }); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Resolvers/GDSequenceResolver.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | internal abstract class GDSequenceResolver : GDResolver 4 | { 5 | public int Index { get; private set; } 6 | 7 | public abstract string Sequence { get; } 8 | 9 | public GDSequenceResolver(ITokenReceiver owner) 10 | : base(owner) 11 | { 12 | } 13 | 14 | internal override void HandleChar(char c, GDReadingState state) 15 | { 16 | var s = Sequence; 17 | 18 | if (s[Index++] == c) 19 | { 20 | if (Index == s.Length) 21 | { 22 | state.Pop(); 23 | OnMatch(state); 24 | } 25 | return; 26 | } 27 | 28 | state.Pop(); 29 | OnFail(state); 30 | 31 | for (int i = 0; i < Index - 1; i++) 32 | state.PassChar(s[i]); 33 | 34 | state.PassChar(c); 35 | } 36 | 37 | protected abstract void OnFail(GDReadingState state); 38 | protected abstract void OnMatch(GDReadingState state); 39 | 40 | internal override void HandleNewLineChar(GDReadingState state) 41 | { 42 | HandleChar('\n', state); 43 | } 44 | 45 | internal override void HandleSharpChar(GDReadingState state) 46 | { 47 | state.Pop(); 48 | OnFail(state); 49 | 50 | var s = Sequence; 51 | 52 | for (int i = 0; i < Index - 1; i++) 53 | state.PassChar(s[i]); 54 | } 55 | 56 | internal override void HandleLeftSlashChar(GDReadingState state) 57 | { 58 | state.Pop(); 59 | OnFail(state); 60 | 61 | var s = Sequence; 62 | 63 | for (int i = 0; i < Index - 1; i++) 64 | state.PassChar(s[i]); 65 | } 66 | 67 | internal override void ForceComplete(GDReadingState state) 68 | { 69 | state.Pop(); 70 | OnFail(state); 71 | 72 | var s = Sequence; 73 | 74 | for (int i = 0; i < Index - 1; i++) 75 | state.PassChar(s[i]); 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Declarations/Class/GDClassMember.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace GDShrapt.Reader 4 | { 5 | public abstract class GDClassMember : GDIntendedNode 6 | { 7 | internal GDClassMember(int intendation) 8 | : base(intendation) 9 | { 10 | } 11 | 12 | internal GDClassMember() 13 | : base() 14 | { 15 | } 16 | 17 | public IEnumerable AttributesDeclaredBefore 18 | { 19 | get 20 | { 21 | var @class = ClassDeclaration; 22 | 23 | if (@class == null) 24 | yield break; 25 | 26 | bool foundThis = false; 27 | 28 | foreach (var item in @class.Members.NodesReversed) 29 | { 30 | if (!foundThis) 31 | { 32 | if (ReferenceEquals(item, this)) 33 | foundThis = true; 34 | } 35 | else 36 | { 37 | if (item is GDCustomAttribute attr) 38 | yield return attr; 39 | else 40 | yield break; 41 | 42 | } 43 | } 44 | } 45 | } 46 | 47 | public IEnumerable AttributesDeclaredBeforeFromStartOfTheClass 48 | { 49 | get 50 | { 51 | var @class = ClassDeclaration; 52 | 53 | if (@class == null) 54 | yield break; 55 | 56 | bool foundThis = false; 57 | 58 | foreach (var item in @class.Members.NodesReversed) 59 | { 60 | if (!foundThis) 61 | { 62 | if (ReferenceEquals(item, this)) 63 | foundThis = true; 64 | } 65 | else 66 | { 67 | if (item is GDCustomAttribute attr) 68 | yield return attr; 69 | } 70 | } 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Resolvers/GDMatchCasesResolver.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | internal class GDMatchCasesResolver : GDIntendedResolver 4 | { 5 | GDSpace _lastSpace; 6 | 7 | new IIntendedTokenReceiver Owner { get; } 8 | 9 | public GDMatchCasesResolver(IIntendedTokenReceiver owner, int lineIntendation) 10 | : base(owner, lineIntendation) 11 | { 12 | Owner = owner; 13 | } 14 | 15 | internal override void HandleCharAfterIntendation(char c, GDReadingState state) 16 | { 17 | if (IsSpace(c)) 18 | { 19 | state.Push(_lastSpace = new GDSpace()); 20 | state.PassChar(c); 21 | return; 22 | } 23 | 24 | SendIntendationTokensToOwner(); 25 | 26 | if (_lastSpace != null) 27 | { 28 | Owner.HandleReceivedToken(_lastSpace); 29 | _lastSpace = null; 30 | } 31 | 32 | Owner.HandleReceivedToken(state.Push(new GDMatchCaseDeclaration(CurrentResolvedIntendationInSpaces))); 33 | state.PassChar(c); 34 | } 35 | 36 | internal override void HandleNewLineAfterIntendation(GDReadingState state) 37 | { 38 | ResetIntendation(); 39 | state.PassNewLine(); 40 | } 41 | 42 | internal override void HandleSharpCharAfterIntendation(GDReadingState state) 43 | { 44 | Owner.HandleReceivedToken(state.Push(new GDComment())); 45 | state.PassSharpChar(); 46 | } 47 | 48 | internal override void HandleLeftSlashCharAfterIntendation(GDReadingState state) 49 | { 50 | Owner.HandleReceivedToken(state.Push(new GDMultiLineSplitToken())); 51 | state.PassLeftSlashChar(); 52 | } 53 | 54 | internal override void ForceComplete(GDReadingState state) 55 | { 56 | if (_lastSpace != null) 57 | { 58 | Owner.HandleReceivedToken(_lastSpace); 59 | _lastSpace = null; 60 | } 61 | 62 | base.ForceComplete(state); 63 | PassIntendationSequence(state); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDStringPart.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace GDShrapt.Reader 4 | { 5 | public sealed class GDStringPart : GDLiteralToken 6 | { 7 | string _sequence; 8 | public override string Sequence 9 | { 10 | get => _sequence; 11 | set => _sequence = value; 12 | } 13 | 14 | public string EscapedSequence 15 | { 16 | get 17 | { 18 | if (_sequence == null) 19 | return null; 20 | 21 | if (_sequence.Length == 0) 22 | return _sequence; 23 | 24 | var builder = new StringBuilder(); 25 | 26 | for (int i = 0; i < _sequence.Length; i++) 27 | { 28 | var ch = _sequence[i]; 29 | 30 | if (ch == '\\' || ch == '\'' || ch == '"') 31 | builder.Append('\\'); 32 | builder.Append(ch); 33 | } 34 | 35 | return builder.ToString(); 36 | } 37 | } 38 | 39 | public GDStringPart() 40 | { 41 | } 42 | 43 | internal override void HandleChar(char c, GDReadingState state) 44 | { 45 | // Nothing 46 | } 47 | 48 | internal override void HandleNewLineChar(GDReadingState state) 49 | { 50 | // Nothing 51 | } 52 | 53 | internal override void HandleSharpChar(GDReadingState state) 54 | { 55 | // Nothing 56 | } 57 | 58 | internal override void HandleLeftSlashChar(GDReadingState state) 59 | { 60 | // Nothing 61 | } 62 | 63 | 64 | public override GDSyntaxToken Clone() 65 | { 66 | return new GDStringPart() 67 | { 68 | Sequence = Sequence 69 | }; 70 | } 71 | 72 | public override string ToString() 73 | { 74 | return $"{Sequence}"; 75 | } 76 | 77 | public override GDLiteralToken CloneWith(string stringValue) 78 | { 79 | return new GDStringPart() 80 | { 81 | Sequence = stringValue 82 | }; 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Building/GD_KEYWORDS.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public static partial class GD 4 | { 5 | public static class Keyword 6 | { 7 | public static GDBreakKeyword Break => new GDBreakKeyword(); 8 | public static GDBreakPointKeyword BreakPoint => new GDBreakPointKeyword(); 9 | public static GDClassKeyword Class => new GDClassKeyword(); 10 | public static GDClassNameKeyword ClassName => new GDClassNameKeyword(); 11 | public static GDConstKeyword Const => new GDConstKeyword(); 12 | public static GDContinueKeyword Continue => new GDContinueKeyword(); 13 | public static GDElifKeyword Elif => new GDElifKeyword(); 14 | public static GDElseKeyword Else => new GDElseKeyword(); 15 | public static GDEnumKeyword Enum => new GDEnumKeyword(); 16 | public static GDExportKeyword Export => new GDExportKeyword(); 17 | public static GDExtendsKeyword Extends => new GDExtendsKeyword(); 18 | public static GDFalseKeyword False => new GDFalseKeyword(); 19 | public static GDForKeyword For => new GDForKeyword(); 20 | public static GDFuncKeyword Func => new GDFuncKeyword(); 21 | public static GDIfKeyword If => new GDIfKeyword(); 22 | public static GDInKeyword In => new GDInKeyword(); 23 | public static GDMatchKeyword Match => new GDMatchKeyword(); 24 | public static GDOnreadyKeyword Onready => new GDOnreadyKeyword(); 25 | public static GDPassKeyword Pass => new GDPassKeyword(); 26 | public static GDReturnKeyword Return => new GDReturnKeyword(); 27 | public static GDSetGetKeyword SetGet => new GDSetGetKeyword(); 28 | public static GDSignalKeyword Signal => new GDSignalKeyword(); 29 | public static GDStaticKeyword Static => new GDStaticKeyword(); 30 | public static GDToolKeyword Tool => new GDToolKeyword(); 31 | public static GDTrueKeyword True => new GDTrueKeyword(); 32 | public static GDVarKeyword Var => new GDVarKeyword(); 33 | public static GDWhileKeyword While => new GDWhileKeyword(); 34 | public static GDYieldKeyword Yield => new GDYieldKeyword(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Lists/GDStatementsList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace GDShrapt.Reader 5 | { 6 | public sealed class GDStatementsList : GDIntendedTokensList 7 | { 8 | bool _completed; 9 | 10 | internal GDStatementsList(int lineIntendation) 11 | : base(lineIntendation) 12 | { 13 | } 14 | 15 | public GDStatementsList() 16 | { 17 | 18 | } 19 | 20 | internal override void HandleChar(char c, GDReadingState state) 21 | { 22 | if (!_completed) 23 | { 24 | _completed = true; 25 | state.Push(new GDStatementsResolver(this, LineIntendationThreshold)); 26 | state.PassChar(c); 27 | return; 28 | } 29 | 30 | state.PopAndPass(c); 31 | } 32 | 33 | internal override void HandleNewLineChar(GDReadingState state) 34 | { 35 | if (!_completed) 36 | { 37 | _completed = true; 38 | state.Push(new GDStatementsResolver(this, LineIntendationThreshold)); 39 | state.PassNewLine(); 40 | return; 41 | } 42 | 43 | state.PopAndPassNewLine(); 44 | } 45 | 46 | public override GDNode CreateEmptyInstance() 47 | { 48 | return new GDStatementsList(); 49 | } 50 | 51 | internal override void Visit(IGDVisitor visitor) 52 | { 53 | visitor.Visit(this); 54 | } 55 | 56 | internal override void Left(IGDVisitor visitor) 57 | { 58 | visitor.Left(this); 59 | } 60 | 61 | public override IEnumerable GetMethodScopeDeclarations(int? beforeLine = null) 62 | { 63 | if (!beforeLine.HasValue) 64 | { 65 | return Form.Direct() 66 | .OfType() 67 | .Select(x => x.Identifier) 68 | .Where(x => x != null); 69 | } 70 | 71 | return Form.Direct() 72 | .OfType() 73 | .Where(x => x.StartLine < beforeLine) 74 | .Select(x => x.Identifier) 75 | .Where(x => x != null); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Lists/GDLayersList.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public class GDLayersList : GDSeparatedList, 4 | ITokenReceiver, 5 | ITokenOrSkipReceiver, 6 | ITokenOrSkipReceiver 7 | { 8 | bool _switch; 9 | bool _ended; 10 | readonly bool _allowNonStringIdentifiers; 11 | 12 | public GDLayersList(bool allowNonStringIdentifiers) 13 | { 14 | _allowNonStringIdentifiers = allowNonStringIdentifiers; 15 | } 16 | 17 | internal override void HandleChar(char c, GDReadingState state) 18 | { 19 | if (this.ResolveSpaceToken(c, state)) 20 | return; 21 | 22 | if (_ended) 23 | { 24 | state.PopAndPass(c); 25 | return; 26 | } 27 | 28 | if (!_switch) 29 | this.ResolvePathSpecifier(c, state, _allowNonStringIdentifiers); 30 | else 31 | this.ResolveColon(c, state); 32 | } 33 | 34 | internal override void HandleNewLineChar(GDReadingState state) 35 | { 36 | _ended = true; 37 | state.PopAndPassNewLine(); 38 | } 39 | 40 | public override GDNode CreateEmptyInstance() 41 | { 42 | return new GDLayersList(_allowNonStringIdentifiers); 43 | } 44 | 45 | internal override void Visit(IGDVisitor visitor) 46 | { 47 | visitor.Visit(this); 48 | } 49 | 50 | internal override void Left(IGDVisitor visitor) 51 | { 52 | visitor.Left(this); 53 | } 54 | 55 | void ITokenReceiver.HandleReceivedToken(GDPathSpecifier token) 56 | { 57 | _switch = !_switch; 58 | ListForm.AddToEnd(token); 59 | } 60 | 61 | void ITokenReceiver.HandleReceivedToken(GDColon token) 62 | { 63 | _switch = !_switch; 64 | ListForm.AddToEnd(token); 65 | } 66 | 67 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 68 | { 69 | _ended = true; 70 | } 71 | 72 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 73 | { 74 | _ended = true; 75 | } 76 | 77 | void ITokenReceiver.HandleReceivedToken(GDSpace token) 78 | { 79 | ListForm.AddToEnd(token); 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Expressions/GDPassExpression.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDPassExpression : GDExpression, 4 | ITokenOrSkipReceiver 5 | { 6 | public override int Priority => GDHelper.GetOperationPriority(GDOperationType.Pass); 7 | 8 | public GDPassKeyword PassKeyword 9 | { 10 | get => _form.Token0; 11 | set => _form.Token0 = value; 12 | } 13 | 14 | public enum State 15 | { 16 | Pass, 17 | Completed 18 | } 19 | 20 | readonly GDTokensForm _form; 21 | public override GDTokensForm Form => _form; 22 | public GDTokensForm TypedForm => _form; 23 | public GDPassExpression() 24 | { 25 | _form = new GDTokensForm(this); 26 | } 27 | 28 | internal override void HandleChar(char c, GDReadingState state) 29 | { 30 | if (_form.IsOrLowerState(State.Pass)) 31 | state.Push(new GDKeywordResolver(this)); 32 | else 33 | state.Pop(); 34 | 35 | state.PassChar(c); 36 | } 37 | 38 | internal override void HandleNewLineChar(GDReadingState state) 39 | { 40 | state.PopAndPassNewLine(); 41 | } 42 | 43 | public override GDNode CreateEmptyInstance() 44 | { 45 | return new GDPassExpression(); 46 | } 47 | 48 | internal override void Visit(IGDVisitor visitor) 49 | { 50 | visitor.Visit(this); 51 | } 52 | 53 | internal override void Left(IGDVisitor visitor) 54 | { 55 | visitor.Left(this); 56 | } 57 | 58 | void ITokenReceiver.HandleReceivedToken(GDPassKeyword token) 59 | { 60 | if (_form.IsOrLowerState(State.Pass)) 61 | { 62 | _form.State = State.Completed; 63 | PassKeyword = token; 64 | return; 65 | } 66 | 67 | throw new GDInvalidStateException(); 68 | } 69 | 70 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 71 | { 72 | if (_form.IsOrLowerState(State.Pass)) 73 | { 74 | _form.State = State.Completed; 75 | return; 76 | } 77 | 78 | throw new GDInvalidStateException(); 79 | } 80 | } 81 | } 82 | 83 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Expressions/GDBreakExpression.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDBreakExpression : GDExpression, 4 | ITokenOrSkipReceiver 5 | { 6 | public override int Priority => GDHelper.GetOperationPriority(GDOperationType.Break); 7 | 8 | public GDBreakKeyword BreakKeyword 9 | { 10 | get => _form.Token0; 11 | set => _form.Token0 = value; 12 | } 13 | 14 | public enum State 15 | { 16 | Break, 17 | Completed 18 | } 19 | 20 | readonly GDTokensForm _form; 21 | public override GDTokensForm Form => _form; 22 | public GDTokensForm TypedForm => _form; 23 | public GDBreakExpression() 24 | { 25 | _form = new GDTokensForm(this); 26 | } 27 | 28 | internal override void HandleChar(char c, GDReadingState state) 29 | { 30 | if (_form.IsOrLowerState(State.Break)) 31 | state.Push(new GDKeywordResolver(this)); 32 | else 33 | state.Pop(); 34 | 35 | state.PassChar(c); 36 | } 37 | 38 | internal override void HandleNewLineChar(GDReadingState state) 39 | { 40 | state.Pop(); 41 | state.PassNewLine(); 42 | } 43 | 44 | public override GDNode CreateEmptyInstance() 45 | { 46 | return new GDBreakExpression(); 47 | } 48 | 49 | internal override void Visit(IGDVisitor visitor) 50 | { 51 | visitor.Visit(this); 52 | } 53 | 54 | internal override void Left(IGDVisitor visitor) 55 | { 56 | visitor.Left(this); 57 | } 58 | 59 | void ITokenReceiver.HandleReceivedToken(GDBreakKeyword token) 60 | { 61 | if (_form.IsOrLowerState(State.Break)) 62 | { 63 | _form.State = State.Completed; 64 | BreakKeyword = token; 65 | return; 66 | } 67 | 68 | throw new GDInvalidStateException(); 69 | } 70 | 71 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 72 | { 73 | if (_form.IsOrLowerState(State.Break)) 74 | { 75 | _form.State = State.Completed; 76 | return; 77 | } 78 | 79 | throw new GDInvalidStateException(); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Expressions/GDContinueExpression.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDContinueExpression : GDExpression, 4 | ITokenOrSkipReceiver 5 | { 6 | public override int Priority => GDHelper.GetOperationPriority(GDOperationType.Continue); 7 | 8 | public GDContinueKeyword ContinueKeyword 9 | { 10 | get => _form.Token0; 11 | set => _form.Token0 = value; 12 | } 13 | 14 | public enum State 15 | { 16 | Continue, 17 | Completed 18 | } 19 | 20 | readonly GDTokensForm _form; 21 | public override GDTokensForm Form => _form; 22 | public GDTokensForm TypedForm => _form; 23 | 24 | public GDContinueExpression() 25 | { 26 | _form = new GDTokensForm(this); 27 | } 28 | 29 | internal override void HandleChar(char c, GDReadingState state) 30 | { 31 | if (_form.IsOrLowerState(State.Continue)) 32 | state.Push(new GDKeywordResolver(this)); 33 | else 34 | state.Pop(); 35 | 36 | state.PassChar(c); 37 | } 38 | 39 | internal override void HandleNewLineChar(GDReadingState state) 40 | { 41 | state.Pop(); 42 | state.PassNewLine(); 43 | } 44 | 45 | public override GDNode CreateEmptyInstance() 46 | { 47 | return new GDContinueExpression(); 48 | } 49 | 50 | internal override void Visit(IGDVisitor visitor) 51 | { 52 | visitor.Visit(this); 53 | } 54 | 55 | internal override void Left(IGDVisitor visitor) 56 | { 57 | visitor.Left(this); 58 | } 59 | 60 | void ITokenReceiver.HandleReceivedToken(GDContinueKeyword token) 61 | { 62 | if (_form.IsOrLowerState(State.Continue)) 63 | { 64 | _form.State = State.Completed; 65 | ContinueKeyword = token; 66 | return; 67 | } 68 | 69 | throw new GDInvalidStateException(); 70 | } 71 | 72 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 73 | { 74 | if (_form.IsOrLowerState(State.Continue)) 75 | { 76 | _form.State = State.Completed; 77 | return; 78 | } 79 | 80 | throw new GDInvalidStateException(); 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Expressions/GDMatchDefaultOperatorExpression.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDMatchDefaultOperatorExpression : GDExpression, 4 | ITokenOrSkipReceiver 5 | { 6 | public override int Priority => GDHelper.GetOperationPriority(GDOperationType.DefaultOperator); 7 | 8 | public GDDefaultToken DefaultToken 9 | { 10 | get => _form.Token0; 11 | set => _form.Token0 = value; 12 | } 13 | 14 | public enum State 15 | { 16 | Default, 17 | Completed 18 | } 19 | 20 | readonly GDTokensForm _form; 21 | public override GDTokensForm Form => _form; 22 | public GDTokensForm TypedForm => _form; 23 | public GDMatchDefaultOperatorExpression() 24 | { 25 | _form = new GDTokensForm(this); 26 | } 27 | 28 | internal override void HandleChar(char c, GDReadingState state) 29 | { 30 | if (_form.IsOrLowerState(State.Default)) 31 | state.Push(new GDSingleCharTokenResolver(this)); 32 | else 33 | state.Pop(); 34 | 35 | state.PassChar(c); 36 | } 37 | 38 | internal override void HandleNewLineChar(GDReadingState state) 39 | { 40 | state.PopAndPassNewLine(); 41 | } 42 | 43 | public override GDNode CreateEmptyInstance() 44 | { 45 | return new GDMatchDefaultOperatorExpression(); 46 | } 47 | 48 | internal override void Visit(IGDVisitor visitor) 49 | { 50 | visitor.Visit(this); 51 | } 52 | 53 | internal override void Left(IGDVisitor visitor) 54 | { 55 | visitor.Left(this); 56 | } 57 | 58 | void ITokenReceiver.HandleReceivedToken(GDDefaultToken token) 59 | { 60 | if (_form.IsOrLowerState(State.Default)) 61 | { 62 | _form.State = State.Completed; 63 | DefaultToken = token; 64 | return; 65 | } 66 | 67 | throw new GDInvalidStateException(); 68 | } 69 | 70 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 71 | { 72 | if (_form.IsOrLowerState(State.Default)) 73 | { 74 | _form.State = State.Completed; 75 | return; 76 | } 77 | 78 | throw new GDInvalidStateException(); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/GDReader.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public abstract class GDReader 4 | { 5 | /// 6 | /// Pass single character in the node. 7 | /// If the node can't handle a character it may return the character to a previous node in the reading state. 8 | /// 9 | /// Character 10 | /// Current reading state 11 | internal abstract void HandleChar(char c, GDReadingState state); 12 | 13 | /// 14 | /// The same but separated method for a new line character 15 | /// 16 | /// Current reading state 17 | internal abstract void HandleNewLineChar(GDReadingState state); 18 | 19 | /// 20 | /// The same but separated method for a back slash character 21 | /// 22 | /// Current reading state 23 | internal abstract void HandleLeftSlashChar(GDReadingState state); 24 | 25 | 26 | /// 27 | /// Simple check on whitespace characters ' ' and '\t'. 28 | /// 29 | /// One char to check 30 | internal bool IsSpace(char c) => c == ' ' || c == '\t'; 31 | 32 | internal bool IsIdentifierStartChar(char c) => c == '_' || char.IsLetter(c); 33 | internal bool IsStringStartChar(char c) => c == '\'' || c == '\"'; 34 | internal bool IsExpressionStopChar(char c) => c == ',' || c == '}' || c == ')' || c == ']' || c == ':' || c == ';'; 35 | internal bool IsNumberStartChar(char c) => char.IsDigit(c); 36 | 37 | 38 | /// 39 | /// The same but separated method for sharp (line commentary) character. 40 | /// Default implementation will add a new comment token in the reading state. 41 | /// 42 | /// Current reading state 43 | internal abstract void HandleSharpChar(GDReadingState state); 44 | 45 | 46 | 47 | /// 48 | /// Force completes token characters handling process in terms of current reading state. 49 | /// Used for situation when the reading code has ended. 50 | /// 51 | /// Current reading state 52 | internal virtual void ForceComplete(GDReadingState state) 53 | { 54 | state.Pop(); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Atributes/GDToolAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDToolAttribute : GDClassAttribute, ITokenOrSkipReceiver 4 | { 5 | public GDToolKeyword ToolKeyword 6 | { 7 | get => _form.Token0; 8 | set => _form.Token0 = value; 9 | } 10 | 11 | public enum State 12 | { 13 | Tool, 14 | Completed 15 | } 16 | 17 | readonly GDTokensForm _form; 18 | public override GDTokensForm Form => _form; 19 | public GDTokensForm TypedForm => _form; 20 | public GDToolAttribute() 21 | { 22 | _form = new GDTokensForm(this); 23 | } 24 | 25 | internal override void HandleChar(char c, GDReadingState state) 26 | { 27 | if (IsSpace(c)) 28 | { 29 | _form.AddBeforeActiveToken(state.Push(new GDSpace())); 30 | state.PassChar(c); 31 | return; 32 | } 33 | 34 | if (_form.IsOrLowerState(State.Tool)) 35 | { 36 | state.PushAndPass(new GDKeywordResolver(this), c); 37 | return; 38 | } 39 | 40 | state.PopAndPass(c); 41 | } 42 | 43 | internal override void HandleNewLineChar(GDReadingState state) 44 | { 45 | state.PopAndPassNewLine(); 46 | } 47 | 48 | public override GDNode CreateEmptyInstance() 49 | { 50 | return new GDToolAttribute(); 51 | } 52 | 53 | internal override void Visit(IGDVisitor visitor) 54 | { 55 | visitor.Visit(this); 56 | } 57 | 58 | internal override void Left(IGDVisitor visitor) 59 | { 60 | visitor.Left(this); 61 | } 62 | 63 | void ITokenReceiver.HandleReceivedToken(GDToolKeyword token) 64 | { 65 | if (_form.IsOrLowerState(State.Tool)) 66 | { 67 | _form.State = State.Completed; 68 | ToolKeyword = token; 69 | return; 70 | } 71 | 72 | throw new GDInvalidStateException(); 73 | } 74 | 75 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 76 | { 77 | if (_form.IsOrLowerState(State.Tool)) 78 | { 79 | _form.State = State.Completed; 80 | return; 81 | } 82 | 83 | throw new GDInvalidStateException(); 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Expressions/GDBreakPointExpression.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDBreakPointExpression : GDExpression, 4 | ITokenOrSkipReceiver 5 | { 6 | public override int Priority => GDHelper.GetOperationPriority(GDOperationType.Breakpoint); 7 | 8 | public GDBreakPointKeyword BreakPointKeyword 9 | { 10 | get => _form.Token0; 11 | set => _form.Token0 = value; 12 | } 13 | 14 | public enum State 15 | { 16 | BreakPoint, 17 | Completed 18 | } 19 | 20 | readonly GDTokensForm _form; 21 | public override GDTokensForm Form => _form; 22 | public GDTokensForm TypedForm => _form; 23 | public GDBreakPointExpression() 24 | { 25 | _form = new GDTokensForm(this); 26 | } 27 | 28 | internal override void HandleChar(char c, GDReadingState state) 29 | { 30 | if (_form.IsOrLowerState(State.BreakPoint)) 31 | state.Push(new GDKeywordResolver(this)); 32 | else 33 | state.Pop(); 34 | 35 | state.PassChar(c); 36 | } 37 | 38 | internal override void HandleNewLineChar(GDReadingState state) 39 | { 40 | state.Pop(); 41 | state.PassNewLine(); 42 | } 43 | 44 | public override GDNode CreateEmptyInstance() 45 | { 46 | return new GDBreakPointExpression(); 47 | } 48 | 49 | internal override void Visit(IGDVisitor visitor) 50 | { 51 | visitor.Visit(this); 52 | } 53 | 54 | internal override void Left(IGDVisitor visitor) 55 | { 56 | visitor.Left(this); 57 | } 58 | 59 | void ITokenReceiver.HandleReceivedToken(GDBreakPointKeyword token) 60 | { 61 | if (_form.IsOrLowerState(State.BreakPoint)) 62 | { 63 | _form.State = State.Completed; 64 | BreakPointKeyword = token; 65 | return; 66 | } 67 | 68 | throw new GDInvalidStateException(); 69 | } 70 | 71 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 72 | { 73 | if (_form.IsOrLowerState(State.BreakPoint)) 74 | { 75 | _form.State = State.Completed; 76 | return; 77 | } 78 | 79 | throw new GDInvalidStateException(); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Types/GDSingleTypeNode.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public class GDSingleTypeNode : GDTypeNode, 4 | ITokenOrSkipReceiver 5 | { 6 | public override bool IsArray => Type?.IsArray ?? false; 7 | public override bool IsDictionary => Type?.IsDictionary ?? false; 8 | 9 | public GDType Type 10 | { 11 | get => _form.Token0; 12 | set => _form.Token0 = value; 13 | } 14 | 15 | public enum State 16 | { 17 | Type, 18 | Completed 19 | } 20 | 21 | readonly GDTokensForm _form; 22 | public override GDTokensForm Form => _form; 23 | public GDTokensForm TypedForm => _form; 24 | 25 | public GDSingleTypeNode() 26 | { 27 | _form = new GDTokensForm(this); 28 | } 29 | 30 | public override GDNode CreateEmptyInstance() 31 | { 32 | return new GDSingleTypeNode(); 33 | } 34 | 35 | internal override void HandleChar(char c, GDReadingState state) 36 | { 37 | if (_form.State == State.Type) 38 | { 39 | if (!this.ResolveSpaceToken(c, state)) 40 | this.ResolveType(c, state); 41 | return; 42 | } 43 | 44 | state.PopAndPass(c); 45 | } 46 | 47 | internal override void HandleNewLineChar(GDReadingState state) 48 | { 49 | _form.State = State.Completed; 50 | state.PopAndPassNewLine(); 51 | } 52 | 53 | internal override void Visit(IGDVisitor visitor) 54 | { 55 | visitor.Visit(this); 56 | } 57 | 58 | internal override void Left(IGDVisitor visitor) 59 | { 60 | visitor.Left(this); 61 | } 62 | 63 | void ITokenReceiver.HandleReceivedToken(GDType token) 64 | { 65 | if (_form.State == State.Type) 66 | { 67 | _form.State = State.Completed; 68 | Type = token; 69 | return; 70 | } 71 | 72 | throw new GDInvalidStateException(); 73 | } 74 | 75 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 76 | { 77 | if (_form.State == State.Type) 78 | { 79 | _form.State = State.Completed; 80 | return; 81 | } 82 | 83 | throw new GDInvalidStateException(); 84 | } 85 | 86 | public override string BuildName() 87 | { 88 | return $"{Type}"; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Types/GDStringTypeNode.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public class GDStringTypeNode : GDTypeNode, 4 | ITokenOrSkipReceiver 5 | { 6 | public override bool IsArray => false; 7 | public override bool IsDictionary => false; 8 | 9 | public GDStringNode Path 10 | { 11 | get => _form.Token0; 12 | set => _form.Token0 = value; 13 | } 14 | 15 | public enum State 16 | { 17 | Path, 18 | Completed 19 | } 20 | 21 | readonly GDTokensForm _form; 22 | public override GDTokensForm Form => _form; 23 | public GDTokensForm TypedForm => _form; 24 | 25 | public GDStringTypeNode() 26 | { 27 | _form = new GDTokensForm(this); 28 | } 29 | 30 | public override GDNode CreateEmptyInstance() 31 | { 32 | return new GDStringTypeNode(); 33 | } 34 | 35 | internal override void HandleChar(char c, GDReadingState state) 36 | { 37 | if (_form.State == State.Path) 38 | { 39 | if (!this.ResolveSpaceToken(c, state)) 40 | this.ResolveString(c, state); 41 | return; 42 | } 43 | 44 | state.PopAndPass(c); 45 | } 46 | 47 | internal override void HandleNewLineChar(GDReadingState state) 48 | { 49 | _form.State = State.Completed; 50 | state.PopAndPassNewLine(); 51 | } 52 | 53 | internal override void Visit(IGDVisitor visitor) 54 | { 55 | visitor.Visit(this); 56 | } 57 | 58 | internal override void Left(IGDVisitor visitor) 59 | { 60 | visitor.Left(this); 61 | } 62 | 63 | void ITokenReceiver.HandleReceivedToken(GDStringNode token) 64 | { 65 | if (_form.State == State.Path) 66 | { 67 | _form.State = State.Completed; 68 | Path = token; 69 | return; 70 | } 71 | 72 | throw new GDInvalidStateException(); 73 | } 74 | 75 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 76 | { 77 | if (_form.State == State.Path) 78 | { 79 | _form.State = State.Completed; 80 | return; 81 | } 82 | 83 | throw new GDInvalidStateException(); 84 | } 85 | 86 | public override string BuildName() 87 | { 88 | return $"{Path}"; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Expressions/GDStringExpression.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDStringExpression : GDExpression, ITokenOrSkipReceiver 4 | { 5 | public override int Priority => GDHelper.GetOperationPriority(GDOperationType.Literal); 6 | public GDStringNode String 7 | { 8 | get => _form.Token0; 9 | set => _form.Token0 = value; 10 | } 11 | 12 | public enum State 13 | { 14 | String, 15 | Completed 16 | } 17 | 18 | readonly GDTokensForm _form; 19 | public override GDTokensForm Form => _form; 20 | public GDTokensForm TypedForm => _form; 21 | public GDStringExpression() 22 | { 23 | _form = new GDTokensForm(this); 24 | } 25 | 26 | internal override void HandleChar(char c, GDReadingState state) 27 | { 28 | if (_form.IsOrLowerState(State.String)) 29 | { 30 | if (this.ResolveSpaceToken(c, state)) 31 | return; 32 | 33 | if (IsStringStartChar(c)) 34 | { 35 | this.ResolveString(c, state); 36 | } 37 | else 38 | { 39 | _form.AddBeforeActiveToken(state.Push(new GDInvalidToken(x => IsStringStartChar(x) || x == '\n'))); 40 | state.PassChar(c); 41 | } 42 | return; 43 | } 44 | 45 | state.PopAndPass(c); 46 | } 47 | 48 | internal override void HandleNewLineChar(GDReadingState state) 49 | { 50 | state.PopAndPassNewLine(); 51 | } 52 | 53 | public override GDNode CreateEmptyInstance() 54 | { 55 | return new GDStringExpression(); 56 | } 57 | 58 | internal override void Visit(IGDVisitor visitor) 59 | { 60 | visitor.Visit(this); 61 | } 62 | 63 | internal override void Left(IGDVisitor visitor) 64 | { 65 | visitor.Left(this); 66 | } 67 | 68 | void ITokenReceiver.HandleReceivedToken(GDStringNode token) 69 | { 70 | if (_form.State == State.String) 71 | { 72 | String = token; 73 | _form.State = State.Completed; 74 | return; 75 | } 76 | 77 | throw new GDInvalidStateException(); 78 | } 79 | 80 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 81 | { 82 | if (_form.State == State.String) 83 | { 84 | _form.State = State.Completed; 85 | return; 86 | } 87 | 88 | throw new GDInvalidStateException(); 89 | } 90 | } 91 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Expressions/GDNumberExpression.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDNumberExpression : GDExpression, 4 | ITokenOrSkipReceiver 5 | { 6 | public override int Priority => GDHelper.GetOperationPriority(GDOperationType.Literal); 7 | public GDNumber Number 8 | { 9 | get => _form.Token0; 10 | set => _form.Token0 = value; 11 | } 12 | 13 | public enum State 14 | { 15 | Number, 16 | Completed 17 | } 18 | 19 | readonly GDTokensForm _form; 20 | public override GDTokensForm Form => _form; 21 | public GDTokensForm TypedForm => _form; 22 | public GDNumberExpression() 23 | { 24 | _form = new GDTokensForm(this); 25 | } 26 | 27 | internal override void HandleChar(char c, GDReadingState state) 28 | { 29 | if (_form.IsOrLowerState(State.Number)) 30 | { 31 | if (IsNumberStartChar(c)) 32 | { 33 | _form.State = State.Completed; 34 | state.Push(Number = new GDNumber()); 35 | state.PassChar(c); 36 | } 37 | else 38 | { 39 | _form.AddBeforeActiveToken(state.Push(new GDInvalidToken(x => IsNumberStartChar(x) || x == '\n'))); 40 | state.PassChar(c); 41 | } 42 | return; 43 | } 44 | 45 | state.PopAndPass(c); 46 | } 47 | 48 | internal override void HandleNewLineChar(GDReadingState state) 49 | { 50 | state.PopAndPassNewLine(); 51 | } 52 | 53 | public override GDNode CreateEmptyInstance() 54 | { 55 | return new GDNumberExpression(); 56 | } 57 | 58 | internal override void Visit(IGDVisitor visitor) 59 | { 60 | visitor.Visit(this); 61 | } 62 | 63 | internal override void Left(IGDVisitor visitor) 64 | { 65 | visitor.Left(this); 66 | } 67 | 68 | void ITokenReceiver.HandleReceivedToken(GDNumber token) 69 | { 70 | if (_form.IsOrLowerState(State.Number)) 71 | { 72 | _form.State = State.Completed; 73 | Number = token; 74 | return; 75 | } 76 | 77 | throw new GDInvalidStateException(); 78 | } 79 | 80 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 81 | { 82 | if (_form.IsOrLowerState(State.Number)) 83 | { 84 | _form.State = State.Completed; 85 | return; 86 | } 87 | 88 | throw new GDInvalidStateException(); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Expressions/GDIdentifierExpression.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace GDShrapt.Reader 4 | { 5 | public sealed class GDIdentifierExpression : GDExpression, 6 | ITokenOrSkipReceiver 7 | { 8 | public override int Priority => GDHelper.GetOperationPriority(GDOperationType.Identifier); 9 | public GDIdentifier Identifier 10 | { 11 | get => _form.Token0; 12 | set => _form.Token0 = value; 13 | } 14 | 15 | public enum State 16 | { 17 | Identifier, 18 | Completed 19 | } 20 | 21 | readonly GDTokensForm _form; 22 | public override GDTokensForm Form => _form; 23 | public GDTokensForm TypedForm => _form; 24 | public GDIdentifierExpression() 25 | { 26 | _form = new GDTokensForm(this); 27 | } 28 | 29 | internal override void HandleChar(char c, GDReadingState state) 30 | { 31 | if (_form.IsOrLowerState(State.Identifier)) 32 | { 33 | _form.State = State.Completed; 34 | state.Push(Identifier = new GDIdentifier()); 35 | state.PassChar(c); 36 | return; 37 | } 38 | 39 | state.PopAndPass(c); 40 | } 41 | 42 | internal override void HandleNewLineChar(GDReadingState state) 43 | { 44 | state.PopAndPassNewLine(); 45 | } 46 | 47 | public override GDNode CreateEmptyInstance() 48 | { 49 | return new GDIdentifierExpression(); 50 | } 51 | 52 | internal override void Visit(IGDVisitor visitor) 53 | { 54 | visitor.Visit(this); 55 | } 56 | 57 | internal override void Left(IGDVisitor visitor) 58 | { 59 | visitor.Left(this); 60 | } 61 | 62 | public override IEnumerable GetDependencies() 63 | { 64 | var identifier = Identifier; 65 | 66 | if (identifier != null) 67 | yield return identifier; 68 | } 69 | 70 | void ITokenReceiver.HandleReceivedToken(GDIdentifier token) 71 | { 72 | if (_form.IsOrLowerState(State.Identifier)) 73 | { 74 | _form.State = State.Completed; 75 | Identifier = token; 76 | return; 77 | } 78 | 79 | throw new GDInvalidStateException(); 80 | } 81 | 82 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 83 | { 84 | if (_form.IsOrLowerState(State.Identifier)) 85 | { 86 | _form.State = State.Completed; 87 | return; 88 | } 89 | 90 | throw new GDInvalidStateException(); 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Atributes/GDCustomAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public class GDCustomAttribute : GDClassAttribute, 4 | ITokenOrSkipReceiver 5 | { 6 | public GDAttribute Attribute 7 | { 8 | get => _form.Token0; 9 | set => _form.Token0 = value; 10 | } 11 | 12 | public enum State 13 | { 14 | Attribute, 15 | Completed 16 | } 17 | 18 | readonly GDTokensForm _form; 19 | public override GDTokensForm Form => _form; 20 | public GDTokensForm TypedForm => _form; 21 | 22 | public GDCustomAttribute() 23 | { 24 | _form = new GDTokensForm(this); 25 | } 26 | 27 | internal GDCustomAttribute(int intendation) 28 | : base(intendation) 29 | { 30 | _form = new GDTokensForm(this); 31 | } 32 | 33 | public override GDNode CreateEmptyInstance() 34 | { 35 | return new GDCustomAttribute(); 36 | } 37 | 38 | internal override void Visit(IGDVisitor visitor) 39 | { 40 | visitor.Visit(this); 41 | } 42 | 43 | internal override void Left(IGDVisitor visitor) 44 | { 45 | visitor.Left(this); 46 | } 47 | 48 | internal override void HandleChar(char c, GDReadingState state) 49 | { 50 | switch (_form.State) 51 | { 52 | case State.Attribute: 53 | if (IsSpace(c)) 54 | { 55 | _form.AddBeforeActiveToken(state.Push(new GDSpace())); 56 | state.PassChar(c); 57 | return; 58 | } 59 | 60 | Attribute = state.PushAndPass(new GDAttribute(), c); 61 | _form.State = State.Completed; 62 | break; 63 | default: 64 | state.PopAndPass(c); 65 | break; 66 | } 67 | } 68 | 69 | internal override void HandleNewLineChar(GDReadingState state) 70 | { 71 | state.PopAndPassNewLine(); 72 | } 73 | 74 | void ITokenReceiver.HandleReceivedToken(GDAttribute token) 75 | { 76 | if (_form.State == State.Attribute) 77 | { 78 | _form.State = State.Completed; 79 | Attribute = token; 80 | return; 81 | } 82 | 83 | throw new GDInvalidStateException(); 84 | } 85 | 86 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 87 | { 88 | if (_form.State == State.Attribute) 89 | { 90 | _form.State = State.Completed; 91 | return; 92 | } 93 | 94 | throw new GDInvalidStateException(); 95 | } 96 | } 97 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Lists/GDStringPartsList.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public class GDStringPartsList : GDSeparatedList, 4 | ITokenOrSkipReceiver, 5 | ITokenOrSkipReceiver 6 | { 7 | bool _firstSlashChecking; 8 | bool _ended; 9 | readonly GDStringBoundingChar _bounder; 10 | 11 | public GDStringPartsList() 12 | { 13 | } 14 | 15 | internal GDStringPartsList(GDStringBoundingChar bounder) 16 | { 17 | _bounder = bounder; 18 | } 19 | 20 | internal override void HandleChar(char c, GDReadingState state) 21 | { 22 | if (_ended) 23 | { 24 | state.PopAndPass(c); 25 | return; 26 | } 27 | 28 | this.ResolveStringPart(c, state, _bounder); 29 | } 30 | 31 | internal override void HandleNewLineChar(GDReadingState state) 32 | { 33 | if (_ended) 34 | { 35 | state.PopAndPassNewLine(); 36 | return; 37 | } 38 | 39 | this.ResolveStringPart('\n', state, _bounder); 40 | } 41 | 42 | internal override void HandleLeftSlashChar(GDReadingState state) 43 | { 44 | if (Count == 0) 45 | { 46 | _firstSlashChecking = true; 47 | this.ResolveStringPart('\\', state, _bounder); 48 | return; 49 | } 50 | 51 | _ended = false; 52 | ListForm.AddToEnd(state.Push(new GDMultiLineSplitToken())); 53 | state.PassLeftSlashChar(); 54 | } 55 | 56 | internal override void HandleSharpChar(GDReadingState state) 57 | { 58 | HandleChar('#', state); 59 | } 60 | 61 | public override GDNode CreateEmptyInstance() 62 | { 63 | return new GDStringPartsList(); 64 | } 65 | 66 | internal override void Left(IGDVisitor visitor) 67 | { 68 | visitor.Left(this); 69 | } 70 | 71 | internal override void Visit(IGDVisitor visitor) 72 | { 73 | visitor.Visit(this); 74 | } 75 | 76 | void ITokenReceiver.HandleReceivedToken(GDStringPart token) 77 | { 78 | ListForm.AddToEnd(token); 79 | } 80 | 81 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 82 | { 83 | if (!_firstSlashChecking) 84 | _ended = true; 85 | else 86 | _firstSlashChecking = false; 87 | } 88 | 89 | void ITokenReceiver.HandleReceivedToken(GDMultiLineSplitToken token) 90 | { 91 | ListForm.AddToEnd(token); 92 | } 93 | 94 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 95 | { 96 | _ended = true; 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Lists/GDSeparatedList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace GDShrapt.Reader 6 | { 7 | public abstract class GDSeparatedList : GDNode, IList 8 | where NODE : GDSyntaxToken 9 | where SEPARATOR : GDSimpleSyntaxToken, new() 10 | { 11 | readonly GDTokensListForm _form; 12 | public GDTokensListForm ListForm => _form; 13 | public override GDTokensForm Form => _form; 14 | 15 | public int Count => _form.Count; 16 | public bool IsReadOnly => false; 17 | 18 | public GDSeparatedList() 19 | { 20 | _form = new GDTokensListForm(this); 21 | } 22 | 23 | internal override void HandleSharpChar(GDReadingState state) 24 | { 25 | Form.AddToEnd(state.Push(new GDComment())); 26 | state.PassSharpChar(); 27 | } 28 | 29 | public new NODE this[int index] 30 | { 31 | get => _form[index]; 32 | set 33 | { 34 | _form[index] = value; 35 | } 36 | } 37 | 38 | public void Add(NODE item) 39 | { 40 | _form.AddToEnd(item); 41 | } 42 | 43 | public void Clear() 44 | { 45 | _form.ClearAllTokens(); 46 | } 47 | 48 | public bool Contains(NODE item) 49 | { 50 | return _form.Contains(item); 51 | } 52 | 53 | public void CopyTo(NODE[] array, int arrayIndex) 54 | { 55 | _form.CopyTo(array, arrayIndex); 56 | } 57 | 58 | public bool Remove(NODE item) 59 | { 60 | return _form.Remove(item); 61 | } 62 | 63 | public IEnumerator GetEnumerator() 64 | { 65 | return ListForm.OfType().GetEnumerator(); 66 | } 67 | 68 | IEnumerator IEnumerable.GetEnumerator() 69 | { 70 | return ListForm.OfType().GetEnumerator(); 71 | } 72 | 73 | public int IndexOf(NODE item) 74 | { 75 | return _form.IndexOf(item); 76 | } 77 | 78 | public void Insert(int index, NODE item) 79 | { 80 | _form.Insert(index, item); 81 | } 82 | 83 | public void RemoveAt(int index) 84 | { 85 | _form.RemoveAt(index); 86 | } 87 | 88 | internal override void WalkIn(IGDVisitor visitor, bool walkBackward) 89 | { 90 | visitor.WillVisit(this); 91 | Visit(visitor); 92 | visitor.EnterNode(this); 93 | 94 | foreach (var node in walkBackward ? NodesReversed : Nodes) 95 | { 96 | visitor.EnterListChild(node); 97 | node.WalkIn(visitor, walkBackward); 98 | visitor.LeftListChild(node); 99 | } 100 | 101 | visitor.LeftNode(); 102 | Left(visitor); 103 | visitor.DidLeft(this); 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDIntendation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace GDShrapt.Reader 5 | { 6 | public sealed class GDIntendation : GDSimpleSyntaxToken 7 | { 8 | int _lineIntendationInSpaces; 9 | 10 | internal StringBuilder _sequenceBuilder = new StringBuilder(); 11 | 12 | public int LineIntendationThreshold { get; set; } 13 | public string Sequence { get; set; } 14 | 15 | internal override void HandleChar(char c, GDReadingState state) 16 | { 17 | if (c == '\t') 18 | { 19 | _sequenceBuilder.Append(c); 20 | _lineIntendationInSpaces += state.Settings.SingleTabSpacesCost; 21 | return; 22 | } 23 | 24 | if (c == ' ') 25 | { 26 | _sequenceBuilder.Append(c); 27 | _lineIntendationInSpaces++; 28 | return; 29 | } 30 | 31 | Sequence = _sequenceBuilder.ToString(); 32 | LineIntendationThreshold = _lineIntendationInSpaces; 33 | 34 | state.PopAndPass(c); 35 | } 36 | 37 | public override GDSyntaxToken Clone() 38 | { 39 | return new GDIntendation() 40 | { 41 | Sequence = Sequence 42 | }; 43 | } 44 | /// 45 | /// Counts all in parents and updates with the count. 46 | /// Also updates the . 47 | /// 48 | /// Whitespace pattern. Used as a single intendation. If null, a single \t character is used. 49 | /// If used not a whitespace pattern 50 | public void Update(string pattern = null) 51 | { 52 | if (pattern == null) 53 | pattern = "\t"; 54 | 55 | if (string.IsNullOrEmpty(pattern)) 56 | throw new ArgumentException("Intendation pattern must not be empty."); 57 | if (!string.IsNullOrWhiteSpace(pattern)) 58 | throw new ArgumentException("Intendation pattern must be a whitespace."); 59 | 60 | var p = Parent; 61 | int intendation = 0; 62 | 63 | while (p != null) 64 | { 65 | if (p is GDIntendedNode) 66 | intendation++; 67 | 68 | p = p.Parent; 69 | } 70 | 71 | LineIntendationThreshold = intendation; 72 | 73 | if (intendation == 0) 74 | Sequence = string.Empty; 75 | else if (intendation == 1) 76 | Sequence = pattern; 77 | else 78 | { 79 | var builder = new StringBuilder(pattern.Length * intendation); 80 | 81 | for (int i = 0; i < intendation; i++) 82 | builder.Append(pattern); 83 | 84 | Sequence = builder.ToString(); 85 | } 86 | } 87 | 88 | public override string ToString() 89 | { 90 | return $"{Sequence}"; 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Resolvers/GDIntendedSequenceResolver.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | internal abstract class GDIntendedSequenceResolver : GDIntendedResolver 4 | { 5 | public int Index { get; private set; } 6 | public abstract string Sequence { get; } 7 | public bool PopStateOnMatch { get; } 8 | 9 | public GDIntendedSequenceResolver(IIntendedTokenReceiver owner, int lineIntendation, bool popStateOnMatch = true) 10 | : base(owner, lineIntendation) 11 | { 12 | PopStateOnMatch = popStateOnMatch; 13 | } 14 | 15 | internal override void HandleCharAfterIntendation(char c, GDReadingState state) 16 | { 17 | var s = Sequence; 18 | 19 | if (s[Index++] == c) 20 | { 21 | if (Index == s.Length) 22 | { 23 | if (PopStateOnMatch) 24 | state.Pop(); 25 | 26 | OnMatch(state); 27 | 28 | if (!PopStateOnMatch) 29 | { 30 | Index = 0; 31 | ResetIntendation(); 32 | } 33 | } 34 | return; 35 | } 36 | 37 | 38 | state.Pop(); 39 | OnFail(state); 40 | 41 | PassIntendationSequence(state); 42 | 43 | for (int i = 0; i < Index - 1; i++) 44 | state.PassChar(s[i]); 45 | 46 | state.PassChar(c); 47 | } 48 | 49 | protected abstract void OnFail(GDReadingState state); 50 | protected abstract void OnMatch(GDReadingState state); 51 | 52 | internal override void HandleNewLineAfterIntendation(GDReadingState state) 53 | { 54 | HandleChar('\n', state); 55 | } 56 | 57 | protected override void OnIntendationThresholdMet(GDReadingState state) 58 | { 59 | base.OnIntendationThresholdMet(state); 60 | OnFail(state); 61 | } 62 | 63 | internal override void ForceComplete(GDReadingState state) 64 | { 65 | var s = Sequence; 66 | state.Pop(); 67 | OnFail(state); 68 | 69 | PassIntendationSequence(state); 70 | 71 | for (int i = 0; i < Index - 1; i++) 72 | state.PassChar(s[i]); 73 | } 74 | 75 | internal override void HandleSharpCharAfterIntendation(GDReadingState state) 76 | { 77 | var s = Sequence; 78 | state.Pop(); 79 | OnFail(state); 80 | 81 | PassIntendationSequence(state); 82 | 83 | for (int i = 0; i < Index - 1; i++) 84 | state.PassChar(s[i]); 85 | 86 | state.PassSharpChar(); 87 | } 88 | 89 | internal override void HandleLeftSlashCharAfterIntendation(GDReadingState state) 90 | { 91 | var s = Sequence; 92 | state.Pop(); 93 | OnFail(state); 94 | 95 | PassIntendationSequence(state); 96 | 97 | for (int i = 0; i < Index - 1; i++) 98 | state.PassChar(s[i]); 99 | 100 | state.PassLeftSlashChar(); 101 | } 102 | } 103 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Basics/GDCharSequence.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace GDShrapt.Reader 4 | { 5 | /// 6 | /// Basic token type to read any sequences of chars 7 | /// 8 | public abstract class GDCharSequence : GDSimpleSyntaxToken 9 | { 10 | StringBuilder _sequenceBuilder = new StringBuilder(); 11 | 12 | internal bool IsCompleted { get; private set; } 13 | public string Sequence { get; protected set; } 14 | 15 | internal int SequenceBuilderLength => _sequenceBuilder.Length; 16 | 17 | internal override void HandleChar(char c, GDReadingState state) 18 | { 19 | if (IsCompleted) 20 | throw new System.Exception("Char sequence already completed"); 21 | 22 | if (CanAppendChar(c, state)) 23 | { 24 | _sequenceBuilder.Append(c); 25 | return; 26 | } 27 | 28 | CompleteSequence(state); 29 | state.PassChar(c); 30 | } 31 | 32 | internal void Append(char c) 33 | { 34 | if (IsCompleted) 35 | throw new System.Exception("Char sequence already completed"); 36 | 37 | _sequenceBuilder.Append(c); 38 | } 39 | 40 | internal void Append(string str) 41 | { 42 | if (IsCompleted) 43 | throw new System.Exception("Char sequence already completed"); 44 | 45 | _sequenceBuilder.Append(str); 46 | } 47 | 48 | internal virtual void CompleteSequence(GDReadingState state) 49 | { 50 | Complete(); 51 | state.Pop(); 52 | } 53 | 54 | internal void Complete() 55 | { 56 | IsCompleted = true; 57 | Sequence = _sequenceBuilder.ToString(); 58 | _sequenceBuilder = null; 59 | } 60 | 61 | internal void ResetSequence() 62 | { 63 | IsCompleted = false; 64 | Sequence = null; 65 | _sequenceBuilder = new StringBuilder(); 66 | } 67 | 68 | internal override void HandleSharpChar(GDReadingState state) 69 | { 70 | Complete(); 71 | base.HandleSharpChar(state); 72 | } 73 | 74 | internal override void HandleNewLineChar(GDReadingState state) 75 | { 76 | Complete(); 77 | base.HandleNewLineChar(state); 78 | } 79 | 80 | internal override void HandleLeftSlashChar(GDReadingState state) 81 | { 82 | Complete(); 83 | base.HandleLeftSlashChar(state); 84 | } 85 | 86 | internal override void ForceComplete(GDReadingState state) 87 | { 88 | CompleteSequence(state); 89 | } 90 | 91 | /// 92 | /// Checks whether the char should be added to current sequence 93 | /// 94 | /// Char to check 95 | /// Current reading state 96 | /// Should add char to sequence 97 | internal abstract bool CanAppendChar(char c, GDReadingState state); 98 | 99 | public override string ToString() 100 | { 101 | return $"{Sequence}"; 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Expressions/GDBoolExpression.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDBoolExpression : GDExpression, 4 | ITokenOrSkipReceiver, 5 | ITokenOrSkipReceiver 6 | { 7 | public override int Priority => GDHelper.GetOperationPriority(GDOperationType.Literal); 8 | 9 | public GDBoolKeyword BoolKeyword 10 | { 11 | get => _form.Token0; 12 | set => _form.Token0 = value; 13 | } 14 | 15 | public bool? Value => BoolKeyword?.Value; 16 | 17 | public enum State 18 | { 19 | True, 20 | False, 21 | Completed 22 | } 23 | 24 | readonly GDTokensForm _form; 25 | public override GDTokensForm Form => _form; 26 | public GDTokensForm TypedForm => _form; 27 | public GDBoolExpression() 28 | { 29 | _form = new GDTokensForm(this); 30 | } 31 | 32 | internal override void HandleChar(char c, GDReadingState state) 33 | { 34 | if (_form.IsOrLowerState(State.True)) 35 | { 36 | this.ResolveKeyword(c, state); 37 | return; 38 | } 39 | 40 | if (_form.IsOrLowerState(State.False)) 41 | { 42 | this.ResolveKeyword(c, state); 43 | return; 44 | } 45 | 46 | state.PopAndPass(c); 47 | } 48 | 49 | internal override void HandleNewLineChar(GDReadingState state) 50 | { 51 | state.PopAndPassNewLine(); 52 | } 53 | 54 | public override GDNode CreateEmptyInstance() 55 | { 56 | return new GDBoolExpression(); 57 | } 58 | 59 | internal override void Visit(IGDVisitor visitor) 60 | { 61 | visitor.Visit(this); 62 | } 63 | 64 | internal override void Left(IGDVisitor visitor) 65 | { 66 | visitor.Left(this); 67 | } 68 | 69 | void ITokenReceiver.HandleReceivedToken(GDTrueKeyword token) 70 | { 71 | if (_form.State != State.Completed) 72 | { 73 | _form.State = State.Completed; 74 | BoolKeyword = token; 75 | return; 76 | } 77 | 78 | throw new GDInvalidStateException(); 79 | } 80 | 81 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 82 | { 83 | if (_form.State != State.Completed) 84 | { 85 | _form.State = State.False; 86 | return; 87 | } 88 | 89 | throw new GDInvalidStateException(); 90 | } 91 | 92 | void ITokenReceiver.HandleReceivedToken(GDFalseKeyword token) 93 | { 94 | if (_form.State != State.Completed) 95 | { 96 | _form.State = State.Completed; 97 | BoolKeyword = token; 98 | return; 99 | } 100 | 101 | throw new GDInvalidStateException(); 102 | } 103 | 104 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 105 | { 106 | if (_form.State != State.Completed) 107 | { 108 | _form.State = State.Completed; 109 | return; 110 | } 111 | 112 | throw new GDInvalidStateException(); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader.Tests/BigScriptTests.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using System.IO; 3 | 4 | namespace GDShrapt.Reader.Tests 5 | { 6 | [TestClass] 7 | public class BigScriptTests 8 | { 9 | [TestMethod] 10 | public void BigScriptParsingTest() 11 | { 12 | var reader = new GDScriptReader(); 13 | 14 | var path = Path.Combine("Scripts", "Sample.gd"); 15 | var declaration = reader.ParseFile(path); 16 | 17 | var fileText = File.ReadAllText(path); 18 | 19 | AssertHelper.CompareCodeStrings(fileText, declaration.ToString()); 20 | AssertHelper.NoInvalidTokens(declaration); 21 | } 22 | 23 | [TestMethod] 24 | public void BigScriptParsingTest2() 25 | { 26 | var reader = new GDScriptReader(); 27 | 28 | var path = Path.Combine("Scripts", "Sample2.gd"); 29 | var declaration = reader.ParseFile(path); 30 | 31 | var fileText = File.ReadAllText(path); 32 | 33 | AssertHelper.CompareCodeStrings(fileText, declaration.ToString()); 34 | AssertHelper.NoInvalidTokens(declaration); 35 | } 36 | 37 | [TestMethod] 38 | public void BigScriptParsingTest3() 39 | { 40 | var reader = new GDScriptReader(); 41 | 42 | var path = Path.Combine("Scripts", "Sample3.gd"); 43 | var declaration = reader.ParseFile(path); 44 | 45 | var fileText = File.ReadAllText(path); 46 | 47 | AssertHelper.CompareCodeStrings(fileText, declaration.ToString()); 48 | AssertHelper.NoInvalidTokens(declaration); 49 | } 50 | 51 | [TestMethod] 52 | public void BigScriptParsingTest4() 53 | { 54 | var reader = new GDScriptReader(); 55 | 56 | var path = Path.Combine("Scripts", "Sample4.gd"); 57 | var declaration = reader.ParseFile(path); 58 | 59 | var fileText = File.ReadAllText(path); 60 | 61 | AssertHelper.CompareCodeStrings(fileText, declaration.ToString()); 62 | AssertHelper.NoInvalidTokens(declaration); 63 | } 64 | 65 | [TestMethod] 66 | public void BigScriptParsingTest5() 67 | { 68 | var reader = new GDScriptReader(); 69 | 70 | var path = Path.Combine("Scripts", "Sample5.gd"); 71 | var declaration = reader.ParseFile(path); 72 | 73 | var fileText = File.ReadAllText(path); 74 | 75 | AssertHelper.CompareCodeStrings(fileText, declaration.ToString()); 76 | AssertHelper.NoInvalidTokens(declaration); 77 | } 78 | 79 | [TestMethod] 80 | public void ScriptTest1() 81 | { 82 | var reader = new GDScriptReader(); 83 | 84 | var code = "# _at_position is not used because it doesn't matter where on the panel\r\n# the item is dropped\r\nfunc _can_drop_data(_at_position: Vector2, data: Variant) -> bool:\t\r\n\tif data is InventoryItem:\r\n\t\t#This is the text that displays uupon pulling an item out.\r\n\t\t%summary.text =( str(\"atk:\" + str(data.physicalattack) +'\\n' + data.lore))\r\n\t\tif type == InventoryItem.Type.MAIN:\r\n\t\t\tif get_child_count() == 0:\r\n\t\t\t\treturn true\r\n\t\t\telse:\r\n\t\t\t\t# Swap two items\r\n\t\t\t\treturn get_child(0).type == data.type\r\n\t\telse:\r\n\t\t\treturn data.type == type\r\n\t\t\t\r\n\t\r\n\treturn false"; 85 | 86 | var declaration = reader.ParseFileContent(code); 87 | 88 | AssertHelper.CompareCodeStrings(code, declaration.ToString()); 89 | AssertHelper.NoInvalidTokens(declaration); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Atributes/GDExtendsAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDExtendsAttribute : GDClassAttribute, 4 | ITokenOrSkipReceiver, 5 | ITokenOrSkipReceiver 6 | { 7 | public GDExtendsKeyword ExtendsKeyword 8 | { 9 | get => _form.Token0; 10 | set => _form.Token0 = value; 11 | } 12 | public GDTypeNode Type 13 | { 14 | get => _form.Token1; 15 | set => _form.Token1 = value; 16 | } 17 | 18 | public enum State 19 | { 20 | Extends, 21 | Type, 22 | Completed 23 | } 24 | 25 | readonly GDTokensForm _form; 26 | public override GDTokensForm Form => _form; 27 | public GDTokensForm TypedForm => _form; 28 | public GDExtendsAttribute() 29 | { 30 | _form = new GDTokensForm(this); 31 | } 32 | 33 | internal override void HandleChar(char c, GDReadingState state) 34 | { 35 | switch (_form.State) 36 | { 37 | case State.Extends: 38 | if (!this.ResolveSpaceToken(c, state)) 39 | this.ResolveKeyword(c, state); 40 | break; 41 | case State.Type: 42 | if (!this.ResolveSpaceToken(c, state)) 43 | this.ResolveType(c, state); 44 | break; 45 | default: 46 | state.PopAndPass(c); 47 | break; 48 | } 49 | } 50 | 51 | internal override void HandleNewLineChar(GDReadingState state) 52 | { 53 | state.PopAndPassNewLine(); 54 | } 55 | 56 | public override GDNode CreateEmptyInstance() 57 | { 58 | return new GDExtendsAttribute(); 59 | } 60 | 61 | internal override void Visit(IGDVisitor visitor) 62 | { 63 | visitor.Visit(this); 64 | } 65 | 66 | internal override void Left(IGDVisitor visitor) 67 | { 68 | visitor.Left(this); 69 | } 70 | 71 | void ITokenReceiver.HandleReceivedToken(GDExtendsKeyword token) 72 | { 73 | if (_form.IsOrLowerState(State.Extends)) 74 | { 75 | _form.State = State.Type; 76 | ExtendsKeyword = token; 77 | return; 78 | } 79 | 80 | throw new GDInvalidStateException(); 81 | } 82 | 83 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 84 | { 85 | if (_form.IsOrLowerState(State.Extends)) 86 | { 87 | _form.State = State.Type; 88 | return; 89 | } 90 | 91 | throw new GDInvalidStateException(); 92 | } 93 | 94 | void ITokenReceiver.HandleReceivedToken(GDTypeNode token) 95 | { 96 | if (_form.IsOrLowerState(State.Type)) 97 | { 98 | _form.State = State.Completed; 99 | Type = token; 100 | return; 101 | } 102 | 103 | throw new GDInvalidStateException(); 104 | } 105 | 106 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 107 | { 108 | if (_form.IsOrLowerState(State.Type)) 109 | { 110 | _form.State = State.Completed; 111 | return; 112 | } 113 | 114 | throw new GDInvalidStateException(); 115 | } 116 | } 117 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Expressions/GDNodePathExpression.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDNodePathExpression : GDExpression, 4 | ITokenOrSkipReceiver, 5 | ITokenOrSkipReceiver 6 | { 7 | public override int Priority => GDHelper.GetOperationPriority(GDOperationType.NodePath); 8 | 9 | public GDSky Sky 10 | { 11 | get => _form.Token0; 12 | set => _form.Token0 = value; 13 | } 14 | 15 | public GDPathList Path 16 | { 17 | get => _form.Token1 ?? (_form.Token1 = new GDPathList()); 18 | set => _form.Token1 = value; 19 | } 20 | 21 | public enum State 22 | { 23 | Sky, 24 | Path, 25 | Completed 26 | } 27 | 28 | readonly GDTokensForm _form; 29 | public override GDTokensForm Form => _form; 30 | public GDTokensForm TypedForm => _form; 31 | public GDNodePathExpression() 32 | { 33 | _form = new GDTokensForm(this); 34 | } 35 | 36 | internal override void HandleChar(char c, GDReadingState state) 37 | { 38 | switch (_form.State) 39 | { 40 | case State.Sky: 41 | if (this.ResolveSpaceToken(c, state)) 42 | return; 43 | this.ResolveSky(c, state); 44 | break; 45 | case State.Path: 46 | _form.State = State.Completed; 47 | state.PushAndPass(Path, c); 48 | break; 49 | default: 50 | state.PopAndPass(c); 51 | break; 52 | } 53 | } 54 | 55 | internal override void HandleNewLineChar(GDReadingState state) 56 | { 57 | state.PopAndPassNewLine(); 58 | } 59 | 60 | public override GDNode CreateEmptyInstance() 61 | { 62 | return new GDNodePathExpression(); 63 | } 64 | 65 | internal override void Visit(IGDVisitor visitor) 66 | { 67 | visitor.Visit(this); 68 | } 69 | 70 | internal override void Left(IGDVisitor visitor) 71 | { 72 | visitor.Left(this); 73 | } 74 | 75 | void ITokenReceiver.HandleReceivedToken(GDSky token) 76 | { 77 | if (_form.IsOrLowerState(State.Sky)) 78 | { 79 | _form.State = State.Path; 80 | Sky = token; 81 | return; 82 | } 83 | 84 | throw new GDInvalidStateException(); 85 | } 86 | 87 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 88 | { 89 | if (_form.IsOrLowerState(State.Sky)) 90 | { 91 | _form.State = State.Path; 92 | return; 93 | } 94 | 95 | throw new GDInvalidStateException(); 96 | } 97 | 98 | void ITokenReceiver.HandleReceivedToken(GDPathList token) 99 | { 100 | if (_form.IsOrLowerState(State.Path)) 101 | { 102 | _form.State = State.Completed; 103 | Path = token; 104 | return; 105 | } 106 | 107 | throw new GDInvalidStateException(); 108 | } 109 | 110 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 111 | { 112 | if(_form.State == State.Path) 113 | { 114 | _form.State = State.Completed; 115 | return; 116 | } 117 | 118 | throw new GDInvalidStateException(); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Building/GD_ATRIBUTE.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GDShrapt.Reader 4 | { 5 | public partial class GD 6 | { 7 | public static class Atribute 8 | { 9 | public static GDToolAttribute Tool() => new GDToolAttribute() 10 | { 11 | ToolKeyword = new GDToolKeyword() 12 | }; 13 | 14 | public static GDClassNameAttribute ClassName() => new GDClassNameAttribute(); 15 | public static GDClassNameAttribute ClassName(Func setup) => setup(new GDClassNameAttribute()); 16 | public static GDClassNameAttribute ClassName(params GDSyntaxToken[] unsafeTokens) => new GDClassNameAttribute() { FormTokensSetter = unsafeTokens }; 17 | public static GDClassNameAttribute ClassName(string identifier) => new GDClassNameAttribute() 18 | { 19 | ClassNameKeyword = new GDClassNameKeyword(), 20 | [1] = Syntax.Space(), 21 | Identifier = Syntax.Identifier(identifier) 22 | }; 23 | 24 | public static GDClassNameAttribute ClassName(GDIdentifier identifier) => new GDClassNameAttribute() 25 | { 26 | ClassNameKeyword = new GDClassNameKeyword(), 27 | [1] = Syntax.Space(), 28 | Identifier = identifier 29 | }; 30 | 31 | public static GDExtendsAttribute Extends() => new GDExtendsAttribute(); 32 | public static GDExtendsAttribute Extends(Func setup) => setup(new GDExtendsAttribute()); 33 | public static GDExtendsAttribute Extends(params GDSyntaxToken[] unsafeTokens) => new GDExtendsAttribute() { FormTokensSetter = unsafeTokens }; 34 | public static GDExtendsAttribute Extends(GDTypeNode type) => new GDExtendsAttribute() 35 | { 36 | ExtendsKeyword = new GDExtendsKeyword(), 37 | [1] = Syntax.Space(), 38 | Type = type 39 | }; 40 | 41 | public static GDExtendsAttribute Extends(string type) => new GDExtendsAttribute() 42 | { 43 | ExtendsKeyword = new GDExtendsKeyword(), 44 | [1] = Syntax.Space(), 45 | Type = GDResolvingHelper.ParseTypeNode(type) 46 | }; 47 | 48 | public static GDExtendsAttribute Extends(GDStringNode path) => new GDExtendsAttribute() 49 | { 50 | ExtendsKeyword = new GDExtendsKeyword(), 51 | [1] = Syntax.Space(), 52 | Type = new GDStringTypeNode() { Path = path } 53 | }; 54 | 55 | /*public static GDExtendsAttribute ExtendsPath(string path) => new GDExtendsAttribute() 56 | { 57 | ExtendsKeyword = new GDExtendsKeyword(), 58 | [1] = Syntax.Space(), 59 | Type = new GDStringTypeNode() { Path = path } 60 | };*/ 61 | 62 | public static GDCustomAttribute Custom() => new GDCustomAttribute(); 63 | public static GDCustomAttribute Custom(Func setup) => setup(new GDCustomAttribute()); 64 | public static GDCustomAttribute Custom(params GDSyntaxToken[] unsafeTokens) => new GDCustomAttribute() { FormTokensSetter = unsafeTokens }; 65 | 66 | public static GDCustomAttribute Custom(GDAttribute attribute) => new GDCustomAttribute() 67 | { 68 | Attribute = attribute 69 | }; 70 | 71 | public static GDCustomAttribute Custom(GDIdentifier identifier) => new GDCustomAttribute() 72 | { 73 | Attribute = new GDAttribute() 74 | { 75 | At = new GDAt(), 76 | Name = identifier 77 | } 78 | }; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Expressions/GDGetNodeExpression.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDGetNodeExpression : GDExpression, 4 | ITokenOrSkipReceiver, 5 | ITokenOrSkipReceiver 6 | { 7 | public override int Priority => GDHelper.GetOperationPriority(GDOperationType.GetNode); 8 | 9 | public GDDollar Dollar 10 | { 11 | get => _form.Token0; 12 | set => _form.Token0 = value; 13 | } 14 | 15 | public GDPathList Path 16 | { 17 | get => _form.Token1 ?? (_form.Token1 = new GDPathList()); 18 | set => _form.Token1 = value; 19 | } 20 | 21 | public enum State 22 | { 23 | Dollar, 24 | Path, 25 | Completed 26 | } 27 | 28 | readonly GDTokensForm _form; 29 | public override GDTokensForm Form => _form; 30 | public GDTokensForm TypedForm => _form; 31 | public GDGetNodeExpression() 32 | { 33 | _form = new GDTokensForm(this); 34 | } 35 | 36 | internal override void HandleChar(char c, GDReadingState state) 37 | { 38 | switch (_form.State) 39 | { 40 | case State.Dollar: 41 | if (this.ResolveSpaceToken(c, state)) 42 | return; 43 | this.ResolveDollar(c, state); 44 | break; 45 | case State.Path: 46 | _form.State = State.Completed; 47 | state.PushAndPass(Path, c); 48 | break; 49 | default: 50 | state.PopAndPass(c); 51 | break; 52 | } 53 | } 54 | 55 | internal override void HandleNewLineChar(GDReadingState state) 56 | { 57 | state.PopAndPassNewLine(); 58 | } 59 | 60 | public override GDNode CreateEmptyInstance() 61 | { 62 | return new GDGetNodeExpression(); 63 | } 64 | 65 | internal override void Visit(IGDVisitor visitor) 66 | { 67 | visitor.Visit(this); 68 | } 69 | 70 | internal override void Left(IGDVisitor visitor) 71 | { 72 | visitor.Left(this); 73 | } 74 | 75 | void ITokenReceiver.HandleReceivedToken(GDDollar token) 76 | { 77 | if (_form.IsOrLowerState(State.Dollar)) 78 | { 79 | _form.State = State.Path; 80 | Dollar = token; 81 | return; 82 | } 83 | 84 | throw new GDInvalidStateException(); 85 | } 86 | 87 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 88 | { 89 | if (_form.IsOrLowerState(State.Dollar)) 90 | { 91 | _form.State = State.Path; 92 | return; 93 | } 94 | 95 | throw new GDInvalidStateException(); 96 | } 97 | 98 | void ITokenReceiver.HandleReceivedToken(GDPathList token) 99 | { 100 | if (_form.IsOrLowerState(State.Path)) 101 | { 102 | _form.State = State.Path; 103 | Path = token; 104 | return; 105 | } 106 | 107 | throw new GDInvalidStateException(); 108 | } 109 | 110 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 111 | { 112 | if (_form.IsOrLowerState(State.Path)) 113 | { 114 | _form.State = State.Path; 115 | return; 116 | } 117 | 118 | throw new GDInvalidStateException(); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Expressions/GDGetUniqueNodeExpression.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDGetUniqueNodeExpression : GDExpression, 4 | ITokenOrSkipReceiver, 5 | ITokenOrSkipReceiver 6 | { 7 | public override int Priority => GDHelper.GetOperationPriority(GDOperationType.GetUniqueNode); 8 | 9 | public GDPercent Percent 10 | { 11 | get => _form.Token0; 12 | set => _form.Token0 = value; 13 | } 14 | 15 | public GDExternalName Name 16 | { 17 | get => _form.Token1; 18 | set => _form.Token1 = value; 19 | } 20 | 21 | public enum State 22 | { 23 | Percent, 24 | Name, 25 | Completed 26 | } 27 | 28 | readonly GDTokensForm _form; 29 | public override GDTokensForm Form => _form; 30 | public GDTokensForm TypedForm => _form; 31 | public GDGetUniqueNodeExpression() 32 | { 33 | _form = new GDTokensForm(this); 34 | } 35 | 36 | internal override void HandleChar(char c, GDReadingState state) 37 | { 38 | switch (_form.State) 39 | { 40 | case State.Percent: 41 | if (this.ResolveSpaceToken(c, state)) 42 | return; 43 | this.ResolvePercent(c, state); 44 | break; 45 | case State.Name: 46 | if (this.ResolveSpaceToken(c, state)) 47 | return; 48 | this.ResolveExternalName(c, state); 49 | break; 50 | default: 51 | state.PopAndPass(c); 52 | break; 53 | } 54 | } 55 | 56 | internal override void HandleNewLineChar(GDReadingState state) 57 | { 58 | state.PopAndPassNewLine(); 59 | } 60 | 61 | public override GDNode CreateEmptyInstance() 62 | { 63 | return new GDGetUniqueNodeExpression(); 64 | } 65 | 66 | internal override void Visit(IGDVisitor visitor) 67 | { 68 | visitor.Visit(this); 69 | } 70 | 71 | internal override void Left(IGDVisitor visitor) 72 | { 73 | visitor.Left(this); 74 | } 75 | 76 | void ITokenReceiver.HandleReceivedToken(GDPercent token) 77 | { 78 | if (_form.IsOrLowerState(State.Percent)) 79 | { 80 | _form.State = State.Name; 81 | Percent = token; 82 | return; 83 | } 84 | 85 | throw new GDInvalidStateException(); 86 | } 87 | 88 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 89 | { 90 | if (_form.IsOrLowerState(State.Percent)) 91 | { 92 | _form.State = State.Name; 93 | return; 94 | } 95 | 96 | throw new GDInvalidStateException(); 97 | } 98 | 99 | void ITokenReceiver.HandleReceivedToken(GDExternalName token) 100 | { 101 | if (_form.IsOrLowerState(State.Name)) 102 | { 103 | _form.State = State.Completed; 104 | Name = token; 105 | return; 106 | } 107 | 108 | throw new GDInvalidStateException(); 109 | } 110 | 111 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 112 | { 113 | if (_form.IsOrLowerState(State.Name)) 114 | { 115 | _form.State = State.Completed; 116 | return; 117 | } 118 | 119 | throw new GDInvalidStateException(); 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Expressions/GDMatchCaseVariableExpression.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDMatchCaseVariableExpression : GDExpression, 4 | ITokenOrSkipReceiver, 5 | ITokenOrSkipReceiver 6 | { 7 | public override int Priority => GDHelper.GetOperationPriority(GDOperationType.MatchCaseVariable); 8 | 9 | public GDVarKeyword VarKeyword 10 | { 11 | get => _form.Token0; 12 | set => _form.Token0 = value; 13 | } 14 | public GDIdentifier Identifier 15 | { 16 | get => _form.Token1; 17 | set => _form.Token1 = value; 18 | } 19 | 20 | public enum State 21 | { 22 | Var, 23 | Identifier, 24 | Completed 25 | } 26 | 27 | readonly GDTokensForm _form; 28 | public override GDTokensForm Form => _form; 29 | public GDTokensForm TypedForm => _form; 30 | public GDMatchCaseVariableExpression() 31 | { 32 | _form = new GDTokensForm(this); 33 | } 34 | 35 | internal override void HandleChar(char c, GDReadingState state) 36 | { 37 | switch (_form.State) 38 | { 39 | case State.Var: 40 | if (!this.ResolveSpaceToken(c, state)) 41 | this.ResolveKeyword(c, state); 42 | break; 43 | case State.Identifier: 44 | if (!this.ResolveSpaceToken(c, state)) 45 | this.ResolveIdentifier(c, state); 46 | break; 47 | default: 48 | state.PopAndPass(c); 49 | break; 50 | } 51 | } 52 | 53 | internal override void HandleNewLineChar(GDReadingState state) 54 | { 55 | state.PopAndPassNewLine(); 56 | } 57 | 58 | public override GDNode CreateEmptyInstance() 59 | { 60 | return new GDMatchCaseVariableExpression(); 61 | } 62 | 63 | internal override void Visit(IGDVisitor visitor) 64 | { 65 | visitor.Visit(this); 66 | } 67 | 68 | internal override void Left(IGDVisitor visitor) 69 | { 70 | visitor.Left(this); 71 | } 72 | 73 | void ITokenReceiver.HandleReceivedToken(GDVarKeyword token) 74 | { 75 | if (_form.IsOrLowerState(State.Var)) 76 | { 77 | _form.State = State.Identifier; 78 | VarKeyword = token; 79 | return; 80 | } 81 | 82 | throw new GDInvalidStateException(); 83 | } 84 | 85 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 86 | { 87 | if (_form.IsOrLowerState(State.Var)) 88 | { 89 | _form.State = State.Identifier; 90 | return; 91 | } 92 | 93 | throw new GDInvalidStateException(); 94 | } 95 | 96 | void ITokenReceiver.HandleReceivedToken(GDIdentifier token) 97 | { 98 | if (_form.IsOrLowerState(State.Identifier)) 99 | { 100 | _form.State = State.Completed; 101 | Identifier = token; 102 | return; 103 | } 104 | 105 | throw new GDInvalidStateException(); 106 | } 107 | 108 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 109 | { 110 | if (_form.IsOrLowerState(State.Identifier)) 111 | { 112 | _form.State = State.Completed; 113 | return; 114 | } 115 | 116 | throw new GDInvalidStateException(); 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Atributes/GDClassNameAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDClassNameAttribute : GDClassAttribute, 4 | ITokenOrSkipReceiver, 5 | ITokenOrSkipReceiver 6 | { 7 | public GDClassNameKeyword ClassNameKeyword 8 | { 9 | get => _form.Token0; 10 | set => _form.Token0 = value; 11 | } 12 | 13 | public GDIdentifier Identifier 14 | { 15 | get => _form.Token1; 16 | set => _form.Token1 = value; 17 | } 18 | 19 | public enum State 20 | { 21 | ClassName, 22 | Identifier, 23 | Completed 24 | } 25 | 26 | readonly GDTokensForm _form; 27 | public override GDTokensForm Form => _form; 28 | public GDTokensForm TypedForm => _form; 29 | 30 | public GDClassNameAttribute() 31 | { 32 | _form = new GDTokensForm(this); 33 | } 34 | 35 | internal override void HandleChar(char c, GDReadingState state) 36 | { 37 | switch (_form.State) 38 | { 39 | case State.ClassName: 40 | if (!this.ResolveSpaceToken(c, state)) 41 | this.ResolveKeyword(c, state); 42 | break; 43 | case State.Identifier: 44 | if (!this.ResolveSpaceToken(c, state)) 45 | this.ResolveIdentifier(c, state); 46 | break; 47 | default: 48 | state.PopAndPass(c); 49 | break; 50 | } 51 | } 52 | 53 | internal override void HandleNewLineChar(GDReadingState state) 54 | { 55 | state.PopAndPassNewLine(); 56 | } 57 | 58 | public override GDNode CreateEmptyInstance() 59 | { 60 | return new GDClassNameAttribute(); 61 | } 62 | 63 | internal override void Visit(IGDVisitor visitor) 64 | { 65 | visitor.Visit(this); 66 | } 67 | 68 | internal override void Left(IGDVisitor visitor) 69 | { 70 | visitor.Left(this); 71 | } 72 | 73 | void ITokenReceiver.HandleReceivedToken(GDClassNameKeyword token) 74 | { 75 | if (_form.IsOrLowerState(State.ClassName)) 76 | { 77 | _form.State = State.Identifier; 78 | ClassNameKeyword = token; 79 | return; 80 | } 81 | 82 | throw new GDInvalidStateException(); 83 | } 84 | 85 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 86 | { 87 | if (_form.IsOrLowerState(State.ClassName)) 88 | { 89 | _form.State = State.Identifier; 90 | return; 91 | } 92 | 93 | throw new GDInvalidStateException(); 94 | } 95 | 96 | void ITokenReceiver.HandleReceivedToken(GDIdentifier token) 97 | { 98 | if (_form.IsOrLowerState(State.Identifier)) 99 | { 100 | _form.State = State.Completed; 101 | Identifier = token; 102 | return; 103 | } 104 | 105 | throw new GDInvalidStateException(); 106 | } 107 | 108 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 109 | { 110 | if (_form.IsOrLowerState(State.Identifier)) 111 | { 112 | _form.State = State.Completed; 113 | return; 114 | } 115 | 116 | throw new GDInvalidStateException(); 117 | } 118 | } 119 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Building/GDBuildingExtensionMethods_KEYWORDS.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public static partial class GDBuildingExtensionMethods 4 | { 5 | public static T AddBreakKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDBreakKeyword()); 6 | public static T AddBreakPointKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDBreakPointKeyword()); 7 | public static T AddClassKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDClassKeyword()); 8 | public static T AddClassNameKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDClassNameKeyword()); 9 | public static T AddConstKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDConstKeyword()); 10 | public static T AddContinueKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDContinueKeyword()); 11 | public static T AddElifKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDElifKeyword()); 12 | public static T AddElseKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDElseKeyword()); 13 | public static T AddEnumKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDEnumKeyword()); 14 | public static T AddExportKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDExportKeyword()); 15 | public static T AddExtendsKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDExtendsKeyword()); 16 | public static T AddFalseKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDFalseKeyword()); 17 | public static T AddForKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDForKeyword()); 18 | public static T AddFuncKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDFuncKeyword()); 19 | public static T AddIfKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDIfKeyword()); 20 | public static T AddInKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDInKeyword()); 21 | public static T AddMatchKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDMatchKeyword()); 22 | public static T AddOnreadyKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDOnreadyKeyword()); 23 | public static T AddPassKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDPassKeyword()); 24 | public static T AddReturnKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDReturnKeyword()); 25 | public static T AddSetGetKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDSetGetKeyword()); 26 | public static T AddSignalKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDSignalKeyword()); 27 | public static T AddStaticKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDStaticKeyword()); 28 | public static T AddToolKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDToolKeyword()); 29 | public static T AddTrueKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDTrueKeyword()); 30 | public static T AddVarKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDVarKeyword()); 31 | public static T AddWhileKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDWhileKeyword()); 32 | public static T AddYieldKeyword(this T receiver) where T : ITokenReceiver => receiver.Add(new GDYieldKeyword()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Statements/GDExpressionStatement.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | public sealed class GDExpressionStatement : GDStatement, 4 | ITokenOrSkipReceiver, 5 | ITokenOrSkipReceiver 6 | { 7 | public GDExpression Expression 8 | { 9 | get => _form.Token0; 10 | set => _form.Token0 = value; 11 | } 12 | public GDSemiColon SemiColon 13 | { 14 | get => _form.Token1; 15 | set => _form.Token1 = value; 16 | } 17 | 18 | public enum State 19 | { 20 | Expression, 21 | SemiColon, 22 | Completed 23 | } 24 | 25 | readonly GDTokensForm _form; 26 | public override GDTokensForm Form => _form; 27 | public GDTokensForm TypedForm => _form; 28 | 29 | internal GDExpressionStatement(int lineIntendation) 30 | : base(lineIntendation) 31 | { 32 | _form = new GDTokensForm(this); 33 | } 34 | 35 | public GDExpressionStatement() 36 | { 37 | _form = new GDTokensForm(this); 38 | } 39 | 40 | internal override void HandleChar(char c, GDReadingState state) 41 | { 42 | switch (_form.State) 43 | { 44 | case State.Expression: 45 | if (!this.ResolveSpaceToken(c, state)) 46 | this.ResolveExpression(c, state, LineIntendation); 47 | break; 48 | case State.SemiColon: 49 | if (!this.ResolveSpaceToken(c, state)) 50 | this.ResolveSemiColon(c, state); 51 | break; 52 | default: 53 | state.PopAndPass(c); 54 | break; 55 | } 56 | } 57 | 58 | internal override void HandleNewLineChar(GDReadingState state) 59 | { 60 | state.PopAndPassNewLine(); 61 | } 62 | 63 | public override GDNode CreateEmptyInstance() 64 | { 65 | return new GDExpressionStatement(); 66 | } 67 | 68 | internal override void Visit(IGDVisitor visitor) 69 | { 70 | visitor.Visit(this); 71 | } 72 | 73 | internal override void Left(IGDVisitor visitor) 74 | { 75 | visitor.Left(this); 76 | } 77 | 78 | void ITokenReceiver.HandleReceivedToken(GDExpression token) 79 | { 80 | if (_form.IsOrLowerState(State.Expression)) 81 | { 82 | _form.State = State.SemiColon; 83 | Expression = token; 84 | return; 85 | } 86 | 87 | throw new GDInvalidStateException(); 88 | } 89 | 90 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 91 | { 92 | if (_form.IsOrLowerState(State.Expression)) 93 | { 94 | _form.State = State.Completed; 95 | return; 96 | } 97 | 98 | throw new GDInvalidStateException(); 99 | } 100 | 101 | void ITokenReceiver.HandleReceivedToken(GDSemiColon token) 102 | { 103 | if (_form.IsOrLowerState(State.SemiColon)) 104 | { 105 | _form.State = State.Completed; 106 | SemiColon = token; 107 | return; 108 | } 109 | 110 | throw new GDInvalidStateException(); 111 | } 112 | 113 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 114 | { 115 | if (_form.IsOrLowerState(State.SemiColon)) 116 | { 117 | _form.State = State.Completed; 118 | return; 119 | } 120 | 121 | throw new GDInvalidStateException(); 122 | } 123 | } 124 | } -------------------------------------------------------------------------------- /src/GDShrapt.Reader/Resolvers/GDDictionaryKeyValueResolver.cs: -------------------------------------------------------------------------------- 1 | namespace GDShrapt.Reader 2 | { 3 | internal class GDDictionaryKeyValueResolver : GDResolver, ITokenOrSkipReceiver 4 | { 5 | readonly int _lineIntendationInSpaces; 6 | bool _keyExpressionChecked; 7 | 8 | ITokenReceiver _receiver; 9 | GDDictionaryKeyValueDeclaration _activeDeclaration; 10 | 11 | private new ITokenOrSkipReceiver Owner { get; } 12 | public INewLineReceiver NewLineReceiver { get; } 13 | 14 | public GDDictionaryKeyValueResolver(ITokenOrSkipReceiver owner, INewLineReceiver newLineReceiver, int lineIntendationInSpaces) 15 | : base(owner) 16 | { 17 | _lineIntendationInSpaces = lineIntendationInSpaces; 18 | Owner = owner; 19 | NewLineReceiver = newLineReceiver; 20 | } 21 | 22 | internal override void HandleChar(char c, GDReadingState state) 23 | { 24 | if (!_keyExpressionChecked) 25 | { 26 | this.ResolveExpression(c, state, _lineIntendationInSpaces, allowAssignment: false); 27 | return; 28 | } 29 | 30 | if (_activeDeclaration == null) 31 | { 32 | Owner.HandleReceivedTokenSkip(); 33 | state.PopAndPass(c); 34 | } 35 | else 36 | { 37 | state.Pop(); 38 | Owner.HandleReceivedToken(_activeDeclaration); 39 | state .PushAndPass(_activeDeclaration, c); 40 | } 41 | } 42 | 43 | internal override void HandleNewLineChar(GDReadingState state) 44 | { 45 | if (!_keyExpressionChecked) 46 | { 47 | NewLineReceiver.HandleReceivedToken(new GDNewLine()); 48 | return; 49 | } 50 | 51 | if (_activeDeclaration == null) 52 | { 53 | Owner.HandleReceivedTokenSkip(); 54 | state.PopAndPassNewLine(); 55 | } 56 | else 57 | { 58 | state.Pop(); 59 | Owner.HandleReceivedToken(_activeDeclaration); 60 | state.PushAndPassNewLine(_activeDeclaration); 61 | } 62 | } 63 | 64 | void ITokenReceiver.HandleReceivedToken(GDExpression token) 65 | { 66 | _activeDeclaration = new GDDictionaryKeyValueDeclaration(); 67 | _activeDeclaration.Add(token); 68 | _receiver = _activeDeclaration; 69 | _keyExpressionChecked = true; 70 | } 71 | 72 | void ITokenSkipReceiver.HandleReceivedTokenSkip() 73 | { 74 | _keyExpressionChecked = true; 75 | } 76 | 77 | public void HandleReceivedToken(GDComment token) 78 | { 79 | if (_activeDeclaration == null) 80 | Owner.HandleReceivedToken(token); 81 | else 82 | _activeDeclaration.Add(token); 83 | } 84 | 85 | public void HandleReceivedToken(GDAttribute token) 86 | { 87 | if (_activeDeclaration == null) 88 | Owner.HandleReceivedToken(token); 89 | else 90 | _receiver.HandleReceivedToken(token); 91 | } 92 | 93 | public void HandleReceivedToken(GDSpace token) 94 | { 95 | if (_activeDeclaration == null) 96 | Owner.HandleReceivedToken(token); 97 | else 98 | _receiver.HandleReceivedToken(token); 99 | } 100 | 101 | public void HandleReceivedToken(GDInvalidToken token) 102 | { 103 | if (_activeDeclaration == null) 104 | Owner.HandleReceivedToken(token); 105 | else 106 | _receiver.HandleReceivedToken(token); 107 | } 108 | 109 | public void HandleReceivedToken(GDMultiLineSplitToken token) 110 | { 111 | if (_activeDeclaration == null) 112 | Owner.HandleReceivedToken(token); 113 | else 114 | _receiver.HandleReceivedToken(token); 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/GDShrapt.Reader/SimpleTokens/GDExternalName.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Text; 4 | 5 | namespace GDShrapt.Reader 6 | { 7 | public sealed class GDExternalName : GDNameToken, IEquatable 8 | { 9 | string _sequence; 10 | public override string Sequence 11 | { 12 | get => _sequence; 13 | set 14 | { 15 | CheckNameValue(value); 16 | _sequence = value; 17 | } 18 | } 19 | 20 | private void CheckNameValue(string value) 21 | { 22 | if (value.IsNullOrWhiteSpace() || value.IsNullOrEmpty()) 23 | throw new ArgumentException("Invalid name format"); 24 | 25 | if (char.IsNumber(value[0])) 26 | throw new ArgumentException("Invalid name format"); 27 | 28 | if (value.Any(x => !char.IsLetter(x) && !char.IsDigit(x) && x != '_')) 29 | throw new ArgumentException("Invalid name format"); 30 | 31 | } 32 | 33 | StringBuilder _builder = new StringBuilder(); 34 | 35 | internal override void HandleChar(char c, GDReadingState state) 36 | { 37 | if (c == '_' || char.IsLetterOrDigit(c)) 38 | { 39 | _builder.Append(c); 40 | } 41 | else 42 | { 43 | Sequence = _builder.ToString(); 44 | state.PopAndPass(c); 45 | } 46 | } 47 | 48 | internal override void HandleNewLineChar(GDReadingState state) 49 | { 50 | if (_builder.Length > 0) 51 | Sequence = _builder.ToString(); 52 | 53 | state.PopAndPassNewLine(); 54 | } 55 | 56 | internal override void HandleSharpChar(GDReadingState state) 57 | { 58 | if (_builder.Length > 0) 59 | Sequence = _builder.ToString(); 60 | base.HandleSharpChar(state); 61 | } 62 | 63 | internal override void ForceComplete(GDReadingState state) 64 | { 65 | if (_builder.Length > 0) 66 | Sequence = _builder.ToString(); 67 | base.ForceComplete(state); 68 | } 69 | 70 | public override GDSyntaxToken Clone() 71 | { 72 | return new GDExternalName() 73 | { 74 | Sequence = Sequence 75 | }; 76 | } 77 | 78 | public static bool operator ==(GDExternalName one, GDExternalName two) 79 | { 80 | if (ReferenceEquals(one, null)) 81 | return ReferenceEquals(two, null); 82 | 83 | if (ReferenceEquals(two, null)) 84 | return false; 85 | 86 | return string.Equals(one.Sequence, two.Sequence, StringComparison.Ordinal); 87 | } 88 | 89 | public static bool operator !=(GDExternalName one, GDExternalName two) 90 | { 91 | if (ReferenceEquals(one, null)) 92 | return !ReferenceEquals(two, null); 93 | 94 | if (ReferenceEquals(two, null)) 95 | return true; 96 | 97 | return !string.Equals(one.Sequence, two.Sequence, StringComparison.Ordinal); 98 | } 99 | 100 | public static implicit operator GDExternalName(string id) 101 | { 102 | return new GDExternalName() 103 | { 104 | Sequence = id 105 | }; 106 | } 107 | 108 | public override int GetHashCode() 109 | { 110 | return Sequence?.GetHashCode() ?? base.GetHashCode(); 111 | } 112 | 113 | public override bool Equals(object obj) 114 | { 115 | if (obj is GDExternalName identifier) 116 | return ReferenceEquals(Sequence, identifier.Sequence) || string.Equals(Sequence, identifier.Sequence, StringComparison.Ordinal); 117 | return base.Equals(obj); 118 | } 119 | 120 | public bool Equals(GDExternalName other) 121 | { 122 | return string.Equals(Sequence, other.Sequence, StringComparison.Ordinal); 123 | } 124 | 125 | public override string ToString() 126 | { 127 | return $"{Sequence}"; 128 | } 129 | } 130 | } --------------------------------------------------------------------------------