Exemplo n.º 1
0
        private DataType _dataType;             // Can be null

        /// <summary>
        /// Creates a function call token.
        /// </summary>
        /// <param name="scope">(required) Current scope</param>
        /// <param name="classToken">(optional) Class name token</param>
        /// <param name="dotToken">(optional) Dot delimiter between class and function name</param>
        /// <param name="nameToken">(required) Function name</param>
        /// <param name="argsToken">(required) Function args</param>
        /// <param name="def">(optional) Existing function definition</param>
        public FunctionCallToken(Scope scope, ClassToken classToken, DotToken dotToken, IdentifierToken nameToken, BracketsToken argsToken, FunctionDefinition def)
            : base(scope)
        {
#if DEBUG
            if (nameToken == null)
            {
                throw new ArgumentNullException("nameToken");
            }
            if (argsToken == null)
            {
                throw new ArgumentNullException("argsToken");
            }
#endif
            AddToken(_classToken = classToken);
            AddToken(dotToken);
            AddToken(_nameToken         = nameToken);
            _nameToken.SourceDefinition = def;
            AddToken(_argsToken         = argsToken);

            _dataType = def.DataType;
        }
Exemplo n.º 2
0
        public static ExpressionToken TryParse(Scope scope, IEnumerable <string> endTokens,
                                               WordTokenCallback wordCallback = null, DataType expectedDataType = null)
        {
            var code = scope.Code;

            code.SkipWhiteSpace();
            var startPos = code.Position;

            // Statement breaking tokens
            if (code.PeekExact(';') || code.PeekExact('{') || code.PeekExact('}'))
            {
                return(null);
            }

            // Caller-specific end tokens
            if (endTokens != null)
            {
                code.Peek();
                if (endTokens.Contains(code.Text))
                {
                    return(null);
                }
            }

            var exp = new ExpressionToken(scope);

            var dataTypeArgs = new DataType.ParseArgs
            {
                Code             = code,
                DataTypeCallback = (name) =>
                {
                    return(scope.DefinitionProvider.GetAny <DataTypeDefinition>(code.Position, name).FirstOrDefault());
                },
                VariableCallback = (name) =>
                {
                    return(scope.DefinitionProvider.GetLocal <VariableDefinition>(code.Position, name).FirstOrDefault());
                },
                Scope = scope,
                TokenCreateCallback = (token) =>
                {
                    exp.AddToken(token);
                },
                VisibleModel = true
            };

            var abortParsing  = false;
            var parseDataType = expectedDataType;

            while (!code.EndOfFile && !abortParsing)
            {
                // Statement breaking tokens
                if (code.PeekExact(';') || code.PeekExact('{') || code.PeekExact('}'))
                {
                    break;
                }
                if (endTokens != null && code.Peek() && endTokens.Contains(code.Text))
                {
                    break;
                }

                if (!code.Read())
                {
                    break;
                }

                switch (code.Type)
                {
                case CodeType.Word:
                {
                    var word     = code.Text;
                    var wordSpan = code.Span;

                    Token token;
                    if (wordCallback != null && (token = wordCallback(word, wordSpan)) != null)
                    {
                        exp.AddToken(token);
                    }
                    else if (parseDataType != null && parseDataType.HasCompletionOptions && parseDataType.IsValidEnumOption(word))
                    {
                        exp.AddToken(new EnumOptionToken(scope, wordSpan, word, parseDataType));
                    }
                    else
                    {
                        var oldPos = code.Position;
                        code.Position = wordSpan.Start;                                         // DataType.TryParse() needs to be before the first word
                        var dt = DataType.TryParse(dataTypeArgs);
                        if (dt == null)
                        {
                            code.Position = oldPos;
                            var wordToken = ProcessWord(exp, scope, word, wordSpan);
                            if (wordToken != null)
                            {
                                exp.AddToken(wordToken);
                            }
                            else
                            {
                                code.Position = wordSpan.Start;
                                abortParsing  = true;
                            }
                        }
                    }
                }
                break;

                case CodeType.Number:
                    exp.AddToken(new NumberToken(scope, code.Span, code.Text));
                    break;

                case CodeType.StringLiteral:
                    if (parseDataType != null && parseDataType.HasCompletionOptions && parseDataType.IsValidEnumOption(code.Text))
                    {
                        exp.AddToken(new EnumOptionToken(scope, code.Span, code.Text, parseDataType));
                    }
                    else
                    {
                        exp.AddToken(new StringLiteralToken(scope, code.Span, code.Text));
                    }
                    break;

                case CodeType.Operator:
                    switch (code.Text)
                    {
                    case "(":
                    {
                        code.Position = code.Span.Start;
                        var bracketsToken = BracketsToken.Parse(scope, parseDataType);
                        if (bracketsToken.IsCast)
                        {
                            exp.AddToken(Statements.CastStatement.Parse(scope, bracketsToken, endTokens));
                        }
                        else
                        {
                            exp.AddToken(bracketsToken);
                        }
                    }
                    break;

                    case "{":
                        code.Position = code.Span.Start;
                        exp.AddToken(BracesToken.Parse(scope, null));
                        break;

                    case "[":
                        code.Position = code.Span.Start;
                        exp.AddToken(ArrayBracesToken.Parse(scope));
                        break;

                    case ",":
                        exp.AddToken(new DelimiterToken(scope, code.Span));
                        break;

                    case ".":
                        exp.AddToken(new DotToken(scope, code.Span));
                        break;

                    case "&":
                        exp.AddToken(new ReferenceToken(scope, code.Span));
                        break;

                    case "==":
                    case "!=":
                    case "<":
                    case "<=":
                    case ">":
                    case ">=":
                        if ((scope.Hint & ScopeHint.SuppressLogic) == 0)
                        {
                            if (exp.ChildrenCount > 0)
                            {
                                var dataType = exp.LastChild.ValueDataType;
                                if (dataType != null)
                                {
                                    parseDataType = dataType;
                                }
                            }
                            exp.AddToken(ComparisonOperator.Parse(scope, exp.LastChild, new OperatorToken(scope, code.Span, code.Text), endTokens));
                        }
                        else
                        {
                            exp.AddToken(new OperatorToken(scope, code.Span, code.Text));
                        }
                        break;

                    case "=":
                        if ((scope.Hint & ScopeHint.SuppressLogic) == 0)
                        {
                            if (exp.ChildrenCount > 0)
                            {
                                var dataType = exp.LastChild.ValueDataType;
                                if (dataType != null)
                                {
                                    parseDataType = dataType;
                                }
                            }
                            exp.AddToken(AssignmentOperator.Parse(scope, exp.LastChild, new OperatorToken(scope, code.Span, code.Text), endTokens));
                        }
                        else
                        {
                            exp.AddToken(new OperatorToken(scope, code.Span, code.Text));
                        }
                        break;

                    case "+=":
                    case "-=":
                    case "*=":
                    case "/=":
                    case "%=":
                        if ((scope.Hint & ScopeHint.SuppressLogic) == 0)
                        {
                            exp.AddToken(AssignmentOperator.Parse(scope, exp.LastChild, new OperatorToken(scope, code.Span, code.Text), endTokens));
                        }
                        else
                        {
                            exp.AddToken(new OperatorToken(scope, code.Span, code.Text));
                        }
                        break;

                    case "?":
                        parseDataType = expectedDataType;
                        exp.AddToken(ConditionalOperator.Parse(scope, exp.LastChild, new OperatorToken(scope, code.Span, code.Text),
                                                               endTokens, parseDataType));
                        break;

                    default:
                        exp.AddToken(new OperatorToken(scope, code.Span, code.Text));
                        break;
                    }
                    break;

                case CodeType.Preprocessor:
                    exp.AddToken(new PreprocessorToken(scope, code.Span, code.Text));
                    break;

                default:
                    exp.AddToken(new UnknownToken(scope, code.Span, code.Text));
                    break;
                }
            }

            if (exp.ChildrenCount == 0)
            {
                return(null);
            }
            return(exp);
        }
Exemplo n.º 3
0
        public FunctionPlaceholderToken(Scope scope, Span span, string text, IdentifierToken nameToken, BracketsToken argsToken, FunctionDefinition sourceDef)
            : base(scope)
        {
#if DEBUG
            if (nameToken == null)
            {
                throw new ArgumentNullException("nameToken");
            }
            if (argsToken == null)
            {
                throw new ArgumentNullException("argsToken");
            }
            if (sourceDef == null)
            {
                throw new ArgumentNullException("sourceDef");
            }
#endif
            AddToken(nameToken);
            AddToken(argsToken);

            nameToken.SourceDefinition = sourceDef;
            _bodyStart = sourceDef.BodyStartPosition;
            _argsEnd   = sourceDef.ArgsEndPosition;
        }
Exemplo n.º 4
0
        public InterfaceMethodCallToken(Scope scope, VariableToken intVarToken, DotToken dotToken, IdentifierToken nameToken, BracketsToken argsToken, InterfaceMethodDefinition def)
            : base(scope)
        {
#if DEBUG
            if (intVarToken == null)
            {
                throw new ArgumentNullException("intVarToken");
            }
            if (dotToken == null)
            {
                throw new ArgumentNullException("dotToken");
            }
            if (nameToken == null)
            {
                throw new ArgumentNullException("nameToken");
            }
            if (argsToken == null)
            {
                throw new ArgumentNullException("argsToken");
            }
            if (def == null)
            {
                throw new ArgumentNullException("def");
            }
#endif
            AddToken(intVarToken);
            AddToken(dotToken);
            AddToken(_nameToken = nameToken);
            AddToken(argsToken);

            _methodDef = def;
            _nameToken.SourceDefinition = def;
        }
Exemplo n.º 5
0
        public static BracketsToken Parse(Scope scope, DataType expectedDataType)
        {
            var code = scope.Code;

            if (!code.ReadExact('('))
            {
                throw new InvalidOperationException("BracketsToken.Parse expected next char to be '('.");
            }
            var openBracketSpan = code.Span;

            var indentScope = scope.CloneIndentNonRoot();

            indentScope.Hint |= ScopeHint.SuppressFunctionDefinition | ScopeHint.SuppressControlStatements | ScopeHint.SuppressStatementStarts;

            var ret = new BracketsToken(scope);

            ret.AddToken(ret._openToken = new OpenBracketToken(scope, openBracketSpan, ret));

            List <Token> dataTypeTokens = null;
            var          dataType       = DataType.TryParse(new DataType.ParseArgs
            {
                Code             = code,
                Scope            = scope,
                DataTypeCallback = name =>
                {
                    return(indentScope.DefinitionProvider.GetAny <Defs.DataTypeDefinition>(openBracketSpan.End, name).FirstOrDefault());
                },
                VariableCallback = name =>
                {
                    return(indentScope.DefinitionProvider.GetAny <Defs.VariableDefinition>(openBracketSpan.End, name).FirstOrDefault());
                },
                TableFieldCallback = (tableName, fieldName) =>
                {
                    foreach (var tableDef in indentScope.DefinitionProvider.GetGlobalFromFile(tableName))
                    {
                        if (tableDef.AllowsChild)
                        {
                            foreach (var fieldDef in tableDef.GetChildDefinitions(fieldName))
                            {
                                return(new Defs.Definition[] { tableDef, fieldDef });
                            }
                        }
                    }

                    return(null);
                },
                TokenCreateCallback = token =>
                {
                    if (dataTypeTokens == null)
                    {
                        dataTypeTokens = new List <Token>();
                    }
                    dataTypeTokens.Add(token);
                },
                VisibleModel = scope.Visible
            });

            if (dataType != null && code.ReadExact(')'))
            {
                ret._cast = dataType;
                if (dataTypeTokens != null)
                {
                    foreach (var token in dataTypeTokens)
                    {
                        ret.AddToken(token);
                    }
                }
                ret.AddToken(ret._closeToken = new CloseBracketToken(scope, code.Span, ret));
            }
            else
            {
                while (!code.EndOfFile)
                {
                    if (code.ReadExact(')'))
                    {
                        ret.AddToken(ret._closeToken = new CloseBracketToken(scope, code.Span, ret));
                        break;
                    }

                    var exp = ExpressionToken.TryParse(indentScope, _endTokens, expectedDataType: expectedDataType);
                    if (exp != null)
                    {
                        ret._innerTokens.Add(exp);
                        ret.AddToken(exp);
                    }
                    else
                    {
                        break;
                    }
                }
            }

            return(ret);
        }
Exemplo n.º 6
0
 public CloseBracketToken(Scope scope, Span span, BracketsToken bracketsToken)
     : base(scope, span, bracketsToken)
 {
 }
Exemplo n.º 7
0
 public BracketToken(Scope scope, Span span, BracketsToken bracketsToken)
     : base(scope, span)
 {
     _bracketsToken = bracketsToken;
     ClassifierType = Classifier.ProbeClassifierType.Operator;
 }