Exemplo n.º 1
0
        public static ConditionalNode Read(ReadParams p, DataType refDataType, Span opSpan, string[] stopStrings)
        {
            var code = p.Code;
            var ret  = new ConditionalNode(p.Statement, opSpan);

            var condStopStrings = stopStrings == null || stopStrings.Length == 0 ? s_stopStrings : stopStrings.Concat(s_stopStrings).ToArray();
            var trueExp         = ExpressionNode.Read(p, refDataType, condStopStrings);

            if (trueExp == null)
            {
                p.Statement.ReportError(new Span(code.Position, code.Position + 1), CAError.CA0042);                    // Expected value to follow conditional '?'.
                return(ret);
            }
            ret._trueExp = trueExp;

            if (!code.ReadExact(':'))
            {
                p.Statement.ReportError(new Span(code.Position, code.Position + 1), CAError.CA0041);                    // Expected ':' to follow conditional result.
                return(ret);
            }

            var falseExp = ExpressionNode.Read(p, refDataType, condStopStrings);

            if (falseExp == null)
            {
                p.Statement.ReportError(new Span(code.Position, code.Position + 1), CAError.CA0043);                    // Expected value to follow conditional ':'.
                return(ret);
            }

            if (code.ReadExact('?'))
            {
                // Stacked conditional
                var group = new GroupNode(p.Statement, null);
                group.AddChild(falseExp);
                group.AddChild(ConditionalNode.Read(p, refDataType, code.Span, stopStrings));
                ret._falseExp = group;
            }
            else
            {
                ret._falseExp = falseExp;
            }

            return(ret);
        }
Exemplo n.º 2
0
        public static ExpressionNode Read(ReadParams p, DataType refDataType, bool stayOnSameLine, params string[] stopStrings)
        {
            ExpressionNode exp           = null;
            var            code          = p.Code;
            var            lastPos       = code.Position;
            var            parseDataType = refDataType;

            while (!code.EndOfFile)
            {
                switch (code.PeekChar())
                {
                case ';':
                case '{':
                case '}':
                    return(exp);
                }

                if (stopStrings != null)
                {
                    foreach (var str in stopStrings)
                    {
                        if (str.IsWord())
                        {
                            if (code.PeekExactWholeWord(str))
                            {
                                return(exp);
                            }
                        }
                        else
                        {
                            if (code.PeekExact(str))
                            {
                                return(exp);
                            }
                        }
                    }
                }

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

                if (stayOnSameLine)
                {
                    if (code.PositionsAreOnDifferentLines(lastPos, code.TokenStartPostion))
                    {
                        code.Position = code.TokenStartPostion;
                        break;
                    }
                    lastPos = code.Position;
                }

                if (exp == null)
                {
                    exp = new ExpressionNode(p.Statement);
                }

                switch (code.Type)
                {
                case CodeType.Number:
                    exp.AddChild(new NumberNode(p.Statement, code.Span, code.Text));
                    break;

                case CodeType.StringLiteral:
                    if (code.Text.StartsWith("'"))
                    {
                        exp.AddChild(new CharLiteralNode(p.Statement, code.Span, CodeParser.StringLiteralToString(code.Text)));
                    }
                    else
                    {
                        exp.AddChild(new StringLiteralNode(p.Statement, code.Span, CodeParser.StringLiteralToString(code.Text)));
                    }
                    break;

                case CodeType.Word:
                    exp.AddChild(exp.ReadWord(p, parseDataType));
                    break;

                case CodeType.Operator:
                    switch (code.Text)
                    {
                    case "(":
                    {
                        var opText    = code.Text;
                        var startPos  = code.Span.Start;
                        var resumePos = code.Position;
                        var dataType  = DataType.TryParse(new DataType.ParseArgs
                            {
                                Code             = code,
                                Flags            = DataType.ParseFlag.Strict,
                                DataTypeCallback = name =>
                                {
                                    return(p.Statement.CodeAnalyzer.PreprocessorModel.DefinitionProvider.
                                           GetAny <DataTypeDefinition>(startPos + p.FuncOffset, name).FirstOrDefault());
                                },
                                VariableCallback = name =>
                                {
                                    return(p.Statement.CodeAnalyzer.PreprocessorModel.DefinitionProvider.
                                           GetAny <VariableDefinition>(startPos + p.FuncOffset, name).FirstOrDefault());
                                },
                                TableFieldCallback = (tableName, fieldName) =>
                                {
                                    foreach (var tableDef in p.Statement.CodeAnalyzer.PreprocessorModel.DefinitionProvider.GetGlobalFromFile(tableName))
                                    {
                                        if (tableDef.AllowsChild)
                                        {
                                            foreach (var fieldDef in tableDef.GetChildDefinitions(fieldName))
                                            {
                                                return(new Definition[] { tableDef, fieldDef });
                                            }
                                        }
                                    }

                                    return(null);
                                },
                                VisibleModel = false
                            });
                        if (dataType != null && code.ReadExact(')'))
                        {
                            // This is a cast
                            var span = new Span(startPos, code.Span.End);
                            exp.AddChild(new CastNode(p.Statement, span, dataType, ExpressionNode.Read(p, dataType, stayOnSameLine, stopStrings)));
                        }
                        else
                        {
                            code.Position = resumePos;
                            exp.AddChild(exp.ReadNestable(p, parseDataType, code.Span, opText, null));
                        }
                    }
                    break;

                    //case "[":
                    //	exp.AddChild(exp.ReadNestable(p, code.Span, code.Text, stopStrings));
                    //	break;
                    case "-":
                    {
                        var lastNode = exp.LastChild;
                        if (lastNode == null || lastNode is OperatorNode)
                        {
                            exp.AddChild(new OperatorNode(p.Statement, code.Span, code.Text, SpecialOperator.UnaryMinus));
                        }
                        else
                        {
                            exp.AddChild(new OperatorNode(p.Statement, code.Span, code.Text, null));
                        }
                    }
                    break;

                    case "?":
                        parseDataType = refDataType;
                        exp.AddChild(ConditionalNode.Read(p, parseDataType, code.Span, stopStrings));
                        break;

                    case "=":
                    {
                        var rDataType = exp.NumChildren > 0 ? exp.LastChild.DataType : null;
                        exp.AddChild(new OperatorNode(p.Statement, code.Span, code.Text, null));
                        exp.AddChild(ExpressionNode.Read(p, rDataType, stopStrings));
                    }
                    break;

                    case "==":
                    case "!=":
                    case "<":
                    case "<=":
                    case ">":
                    case ">=":
                    {
                        if (exp.NumChildren > 0)
                        {
                            var dt = exp.LastChild.DataType;
                            if (dt != null)
                            {
                                parseDataType = dt;
                            }
                        }
                        exp.AddChild(new OperatorNode(p.Statement, code.Span, code.Text, null));
                    }
                    break;

                    default:
                        exp.AddChild(new OperatorNode(p.Statement, code.Span, code.Text, null));
                        break;
                    }
                    break;

                default:
                    exp.ReportError(code.Span, CAError.CA0001, code.Text);                              // Unknown '{0}'.
                    exp.AddChild(new UnknownNode(p.Statement, code.Span, code.Text));
                    break;
                }
            }

            return(exp);
        }