private static SwitchExpression CompileState <OutputT>(TransducerState <Char, OutputT> state, ParameterExpression reader, ParameterExpression output, LabelTarget @return, Int32 depth) { var idx = 0; var cases = new SwitchCase[state.TransitionTable.Count]; foreach (KeyValuePair <Char, TransducerState <Char, OutputT> > statePair in state.TransitionTable) { cases[idx++] = Expression.SwitchCase( CompileState(statePair.Value, reader, output, @return, depth + 1), Expression.Constant((Char?)statePair.Key) ); } return(Expression.Switch( GExpression.MethodCall <ICodeReader>(reader, r => r.Peek(depth), depth), state.IsTerminal ? Expression.Block( GExpression.MethodCall <ICodeReader>(reader, r => r.Advance(0), depth + 1), Expression.Assign(output, Expression.Constant(state.Output)), Expression.Return(@return, Expression.Constant(true)) ) : (Expression)Expression.Return(@return, Expression.Constant(false)), cases )); }
private static SwitchExpression CompileState <TTokenType, OutputT>(TransducerState <Token <TTokenType>, OutputT> state, ParameterExpression reader, ParameterExpression output, LabelTarget @return, Int32 depth) where TTokenType : notnull { var idx = 0; var cases = new SwitchCase[state.TransitionTable.Count]; foreach (KeyValuePair <Token <TTokenType>, TransducerState <Token <TTokenType>, OutputT> > statePair in state.TransitionTable) { cases[idx++] = Expression.SwitchCase( CompileState(statePair.Value, reader, output, @return, depth + 1), Expression.Constant(statePair.Key) ); } return(Expression.Switch( GExpression.MethodCall <ITokenReader <TTokenType> >(reader, r => r.Lookahead(depth), depth), state.IsTerminal ? Expression.Block( GExpression.MethodCall <ITokenReader <TTokenType> >(reader, r => r.Skip(0), depth + 1), Expression.Assign(output, Expression.Constant(state.Output)), Expression.Return(@return, Expression.Constant(true)) ) : (Expression)Expression.Constant(false), cases )); }