﻿// Copyright 2012 Fan Shi
// 
// This file is part of the VBF project.
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;

namespace VBF.Compilers.Parsers.Combinators
{
    public class ConcatenationParser<T1, T2, TR> : Parser<TR>
    {
        public ConcatenationParser(Parser<T1> parserLeft, Func<T1, Parser<T2>> parserRightSelector, Func<T1, T2, TR> selector)
        {
            CodeContract.RequiresArgumentNotNull(parserLeft, "parserLeft");
            CodeContract.RequiresArgumentNotNull(parserRightSelector, "parserRightSelector");
            CodeContract.RequiresArgumentNotNull(selector, "selector");

            ParserLeft = parserLeft;
            ParserRightSelector = parserRightSelector;
            Selector = selector;
        }

        public Parser<T1> ParserLeft { get; private set; }
        public Func<T1, Parser<T2>> ParserRightSelector { get; private set; }
        public Func<T1, T2, TR> Selector { get; private set; }

        public override ParserFunc<TFuture> BuildParser<TFuture>(Future<TR, TFuture> future)
        {
            return (scanner, context) => 
                ParserLeft.BuildParser(
                    left => ParserRightSelector(left).BuildParser(
                        right => future(Selector(left, right))))(scanner, context);
        }
        
    }
}
