private void EmitConsumeEntry(ILBuilderContext ilBuilderContext, ParserStateEntry parserStateEntry, LocalBuilder resultLocal) { var parserEntry = parserStateEntry?.ParserEntryData; if (parserEntry == null || parserEntry.FlatIndex == -1) { return; } var parserProduction = parserEntry.ParserProduction; var argumentBuilder = parserProduction.Binder.Template[parserEntry.FlatIndex]; if (!(argumentBuilder is ParserArgumentBuilder parserArgumentBuilder)) { throw new InvalidOperationException(); } ilBuilderContext.EmitLdContext(); ilBuilderContext.IL.Emit(OpCodes.Call, PeekStateEntryMethodInfo); ilBuilderContext.IL.Emit(OpCodes.Ldfld, ProductionInstanceBuilderArgumentsFieldInfo); ilBuilderContext.IL.Emit(OpCodes.Ldc_I4, parserEntry.FlatIndex); ilBuilderContext.IL.Emit(OpCodes.Ldelem_Ref); ilBuilderContext.IL.Emit(OpCodes.Ldloc, resultLocal); parserArgumentBuilder.EmitConsumeValue(ilBuilderContext); if (parserProduction.Binder.TryReturn) { ilBuilderContext.EmitLdContext(); ilBuilderContext.IL.Emit(OpCodes.Ldc_I4, parserEntry.FlatIndex); ilBuilderContext.IL.Emit(OpCodes.Call, OnAfterConsumeValueMethodInfo); } }
protected static ArgumentBuilder CreateArgumentBuilder(Type type, ParameterInfo parameterInfo, ParserEntryData flatEntryData) { var parserEntry = flatEntryData.ParserEntry; return(parserEntry switch { IParserPredicate parserPredicateEntry => CreatePredicateArgumentBuilder(type, parserPredicateEntry), ParserSetMatchEntry parserSetMatchEntry => CreateLexerArgumentBuilder(type, null, parserSetMatchEntry), ParserSingleMatchEntry parserSingleMatchEntry => CreateLexerArgumentBuilder(type, null, parserSingleMatchEntry), ParserStateEntry parserStateEntry => CreateParserArgumentBuilder(type), _ => throw new ArgumentOutOfRangeException(nameof(parserEntry)) });