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); }
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); }