slicec 0.4.0

The Slice parser and other core components for Slice compilers.
Documentation
// Copyright (c) ZeroC, Inc.

pub mod ast;
pub mod compilation_state;
pub mod diagnostic_emitter;
pub mod diagnostics;
pub mod grammar;
pub mod slice_file;
pub mod slice_options;
pub mod utils;
pub mod visitor;

mod parsers;
mod patchers;
mod validators;

use compilation_state::CompilationState;
use slice_file::SliceFile;
use slice_options::SliceOptions;
use std::collections::HashSet;
use utils::file_util;

pub fn compile_from_options(options: &SliceOptions) -> CompilationState {
    // Create an instance of `CompilationState` for holding all the compiler's state.
    let mut state = CompilationState::create();

    // Disable colored output if the user requested we do so.
    if options.disable_color {
        console::set_colors_enabled(false);
        console::set_colors_enabled_stderr(false);
    }

    // Recursively resolve any Slice files contained in the paths specified by the user.
    state.files = file_util::resolve_files_from(options, &mut state.diagnostics);

    // If any files were unreadable, return without parsing. Otherwise, parse the files normally.
    if !state.diagnostics.has_errors() {
        compile_files(&mut state, options);
    }
    state
}

pub fn compile_from_strings(inputs: &[&str], options: Option<&SliceOptions>) -> CompilationState {
    // Create an instance of `CompilationState` for holding all the compiler's state.
    let mut state = CompilationState::create();

    // Disable colored output if the user requested we do so.
    if options.map(|opts| opts.disable_color).unwrap_or_default() {
        console::set_colors_enabled(false);
        console::set_colors_enabled_stderr(false);
    }

    // Create a Slice file from each of the strings.
    for (i, &input) in inputs.iter().enumerate() {
        let slice_file = SliceFile::new(format!("string-{i}"), input.to_owned(), false);
        state.files.push(slice_file);
    }

    match options {
        Some(slice_options) => compile_files(&mut state, slice_options),
        None => compile_files(&mut state, &SliceOptions::default()),
    }

    state
}

fn compile_files(state: &mut CompilationState, options: &SliceOptions) {
    // Retrieve any preprocessor symbols defined by the compiler itself, or by the user on the command line.
    let defined_symbols = HashSet::from_iter(options.defined_symbols.clone());

    // There are several phases of compilation handled by `slicec`:
    // 1) Parse the files passed in by the user.
    // 2) Patch the abstract syntax tree generated by the parser.
    // 3) Validate the AST, checking for language-mapping agnostic errors.
    parsers::parse_files(state, &defined_symbols);
    unsafe { state.apply_unsafe(patchers::patch_ast) };
    state.apply(validators::validate_ast);
}