Esempio n. 1
0
        private static void HandleNextOperator(
            OperatorToken opToken,
            List <ParsingUnit> units,
            IEnumerator <Token> tokens,
            CompilationContext context)
        {
            switch (opToken.operatorType)
            {
            case Operator.Assignment:
            case Operator.PlusEquals:
            case Operator.MinusEquals:
            case Operator.TimesEquals:
            case Operator.DivideEquals:
            case Operator.PowerEquals:
            case Operator.ModuloEquals:
            case Operator.AndEquals:
            case Operator.OrEquals:
            case Operator.Plus:
            case Operator.Minus:
            case Operator.Times:
            case Operator.Divide:
            case Operator.Power:
            case Operator.Modulo:
            case Operator.CastDouble:
            case Operator.CastInteger:
            case Operator.Increment:
            case Operator.Decrement:
            case Operator.Not:
            case Operator.IsEqualTo:
            case Operator.IsNotEqualTo:
            case Operator.IsGreaterThan:
            case Operator.IsGreaterThanOrEqualTo:
            case Operator.IsLessThan:
            case Operator.IsLessThanOrEqualTo:
            case Operator.And:
            case Operator.Or:
            case Operator.Negate:
                //Add and continue
                units.Add(new TokenUnit(opToken));
                tokens.CautiousAdvance();
                break;

            case Operator.Ternary:
                //Add the ternary Operator
                units.Add(new TokenUnit(opToken));
                tokens.CautiousAdvance();

                //Add the first expected expression
                Token firstToken = tokens.Current;
                units.Add(new ParsedValuedUnit(
                              value: ParseNextExpression(tokens, context),
                              firstToken: firstToken));

                //Colon
                tokens.AssertAndSkip(Separator.Colon);

                //Add the second expected expression
                firstToken = tokens.Current;
                units.Add(new ParsedValuedUnit(
                              value: ParseNextExpression(tokens, context),
                              firstToken: firstToken));
                break;

            case Operator.MemberAccess:
                tokens.CautiousAdvance();
                IdentifierToken nameToken = tokens.GetTokenAndAdvance <IdentifierToken>();
                if (tokens.TestWithoutSkipping(Separator.OpenParen))
                {
                    //Method
                    units.Add(new MemberAccessUnit(
                                  identifier: nameToken.identifier,
                                  args: ParseArguments(tokens, context),
                                  firstToken: opToken));
                }
                else
                {
                    //Value
                    units.Add(new MemberAccessUnit(
                                  identifier: nameToken.identifier,
                                  args: null,
                                  firstToken: opToken));
                }
                break;


            case Operator.AmbiguousMinus:
            default:
                throw new ArgumentException($"Unsupported Operator: {opToken.operatorType}");
            }
        }
Esempio n. 2
0
        private static void HandleNextKeyword(
            KeywordToken keywordToken,
            List <ParsingUnit> units,
            IEnumerator <Token> tokens,
            CompilationContext context)
        {
            switch (keywordToken.keyword)
            {
            case Keyword.New:
            {
                tokens.CautiousAdvance();
                Type newObjectType = tokens.ReadType();

                IValueGetter[] args = ParseArguments(tokens, context);

                if (tokens.TestWithoutSkipping(Separator.OpenCurlyBoi))
                {
                    Type itemType = newObjectType.GetInitializerItemType();
                    if (itemType == null)
                    {
                        throw new ScriptParsingException(
                                  source: keywordToken,
                                  message: $"Initializer Lists only function on collections. " +
                                  $"Did you enter the wrong type, or possibly omit a semicolon at the end of the expression?");
                    }

                    //Initializer Syntax
                    IValueGetter[] items = ParseItems(tokens, itemType, context);

                    units.Add(new ParsedValuedUnit(
                                  value: new ConstructInitializedCollectionExpression(
                                      objectType: newObjectType,
                                      args: args,
                                      items: items,
                                      source: keywordToken),
                                  firstToken: keywordToken));
                }
                else
                {
                    units.Add(new ParsedValuedUnit(
                                  value: new ConstructObjectExpression(
                                      objectType: newObjectType,
                                      args: args),
                                  firstToken: keywordToken));
                }
            }
            break;

            case Keyword.System:
            case Keyword.User:
            case Keyword.Math:
            case Keyword.Debug:
            {
                tokens.CautiousAdvance();
                tokens.AssertAndSkip(Operator.MemberAccess);
                IdentifierToken identifierToken = tokens.GetTokenAndAdvance <IdentifierToken>();
                if (tokens.TestWithoutSkipping(Operator.IsLessThan))
                {
                    //Generic Method
                    Type[] internalTypes = tokens.ReadTypeArguments();

                    units.Add(new ParsedValuedUnit(
                                  value: MemberManagement.HandleStaticGenericMethodExpression(
                                      keywordToken: keywordToken,
                                      args: ParseArguments(tokens, context),
                                      identifier: identifierToken.identifier,
                                      genericTypes: internalTypes),
                                  firstToken: keywordToken));
                }
                else if (tokens.TestWithoutSkipping(Separator.OpenParen))
                {
                    //Method
                    units.Add(new ParsedValuedUnit(
                                  value: MemberManagement.HandleStaticMethodExpression(
                                      keywordToken: keywordToken,
                                      args: ParseArguments(tokens, context),
                                      identifier: identifierToken.identifier),
                                  firstToken: keywordToken));
                }
                else
                {
                    //Member
                    units.Add(new ParsedValuedUnit(
                                  value: MemberManagement.HandleStaticMemberExpression(
                                      keywordToken: keywordToken,
                                      identifier: identifierToken.identifier),
                                  firstToken: keywordToken));
                }
            }
            break;

            default:
                units.Add(new TokenUnit(tokens.Current));
                tokens.CautiousAdvance();
                break;
            }
        }
Esempio n. 3
0
        public void ParseNextGlobal(
            IEnumerator <Token> scriptTokens,
            ScriptCompilationContext context)
        {
            switch (scriptTokens.Current)
            {
            case KeywordToken kwToken:
                //Valid operations:
                //  Global declaration
                //  Extern declaration
                //  Member declaration
                //  Class declaration
                switch (kwToken.keyword)
                {
                case Keyword.Global:
                case Keyword.Extern:
                    //Parse Global Declaration
                {
                    scriptTokens.CautiousAdvance();

                    Type valueType = scriptTokens.ReadType();

                    IdentifierToken identToken            = scriptTokens.GetTokenAndAdvance <IdentifierToken>();
                    IValueGetter    initializerExpression = null;

                    if (scriptTokens.TestAndConditionallySkip(Operator.Assignment))
                    {
                        initializerExpression = Expression.ParseNextGetterExpression(scriptTokens, context);
                    }

                    scriptTokens.AssertAndSkip(Separator.Semicolon, false);

                    scriptDeclarations.Add(
                        new GlobalDeclaration(
                            identifierToken: identToken,
                            valueType: valueType,
                            isExtern: kwToken.keyword == Keyword.Extern,
                            initializer: initializerExpression,
                            context: context));
                }
                    return;

                case Keyword.Const:
                {
                    scriptTokens.CautiousAdvance();

                    Type valueType = scriptTokens.ReadType();

                    IdentifierToken identToken = scriptTokens.GetTokenAndAdvance <IdentifierToken>();
                    scriptTokens.AssertAndSkip(Operator.Assignment);
                    IValueGetter initializerExpression = Expression.ParseNextGetterExpression(scriptTokens, context);

                    scriptTokens.AssertAndSkip(Separator.Semicolon, false);

                    if (!(initializerExpression is LiteralToken litToken))
                    {
                        throw new ScriptParsingException(
                                  source: kwToken,
                                  message: $"The value of Const declarations must be constant");
                    }

                    object value = litToken.GetAs <object>();

                    if (!valueType.IsAssignableFrom(litToken.GetValueType()))
                    {
                        value = Convert.ChangeType(value, valueType);
                    }

                    context.DeclareConstant(
                        identifierToken: identToken,
                        type: valueType,
                        value: value);
                }
                    return;

                case Keyword.Void:
                case Keyword.Bool:
                case Keyword.Double:
                case Keyword.Integer:
                case Keyword.String:
                case Keyword.List:
                case Keyword.Queue:
                case Keyword.Stack:
                case Keyword.DepletableBag:
                case Keyword.DepletableList:
                case Keyword.RingBuffer:
                case Keyword.Dictionary:
                case Keyword.HashSet:
                case Keyword.Random:
                case Keyword.DataFile:
                    //Parse Function or Member Declaration
                {
                    Type            valueType  = scriptTokens.ReadType();
                    IdentifierToken identToken = scriptTokens.GetTokenAndAdvance <IdentifierToken>();

                    if (scriptTokens.TestWithoutSkipping(Separator.OpenParen))
                    {
                        VariableData[] arguments = ParseArgumentsDeclaration(scriptTokens);

                        if (scriptFunctions.ContainsKey(identToken.identifier))
                        {
                            throw new ScriptParsingException(
                                      source: identToken,
                                      message: $"Two declarations of function {identToken.identifier} found.");
                        }

                        scriptFunctions.Add(identToken.identifier,
                                            new ScriptFunction(
                                                functionTokens: scriptTokens,
                                                functionSignature: new FunctionSignature(
                                                    identifierToken: identToken,
                                                    returnType: valueType,
                                                    arguments: arguments),
                                                context: context));
                    }
                    else
                    {
                        //Member declaration
                        if (kwToken.keyword == Keyword.Void)
                        {
                            throw new ScriptParsingException(
                                      source: kwToken,
                                      message: $"Cannot declare a member of type Void");
                        }

                        IValueGetter initializerExpression = null;
                        if (scriptTokens.TestAndConditionallySkip(Operator.Assignment))
                        {
                            initializerExpression = Expression.ParseNextGetterExpression(scriptTokens, context);
                        }

                        scriptTokens.AssertAndSkip(Separator.Semicolon, false);

                        scriptDeclarations.Add(
                            new MemberDeclaration(
                                identifierToken: identToken,
                                valueType: valueType,
                                initializer: initializerExpression,
                                context: context));
                    }
                }
                    return;

                default:
                    throw new ScriptParsingException(
                              source: kwToken,
                              message: $"Token not valid for global context: {kwToken}.");
                }

            default:
                throw new ScriptParsingException(
                          source: scriptTokens.Current,
                          message: $"Token not valid for global context: {scriptTokens.Current}.");
            }
        }