subcomponent 0.1.0

A components orchestrator
/*
 * Copyright (c) 2016-2017 Jean Guyomarc'h
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

extern crate std;
pub mod lexer;
#[macro_use] pub mod parser;

use std::error::Error as FmtError;
use self::Error::*;

#[derive(Debug)]
pub enum Error {
    LexingError(lexer::Error),
    ParsingError(parser::Error),
}

impl From<lexer::Error> for Error {
    fn from(error: lexer::Error) -> Self {
        LexingError(error)
    }
}

impl From<parser::Error> for Error {
    fn from(error: parser::Error) -> Self {
        ParsingError(error)
    }
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", self.description())
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            LexingError(ref err) => err.description(),
            ParsingError(ref err) => err.description(),
        }
    }
}

pub fn compile(entry: &std::path::Path) -> Result<parser::Parser, Error> {
    /* First phase: tokenization (lexing) */
    let mut lexer = lexer::new();
    let ret = lexer.lex(entry);
    match ret {
        Ok(_) => {},
        Err(err) => {
            error!("Lexing phase failed, errors have been encountered");
            let errors = lexer.errors_get();
            for l_err in errors {
                error!(" > in file {} at line {}, column {}: {}",
                       l_err.file,
                       l_err.line, l_err.column,
                       l_err.message);
            }
            return Err(LexingError(err));
        }
    }

    /* Second phase: parsing */
    let mut parser = parser::Parser::new();
    try!(parser.parse(&lexer));

    Ok(parser)
}