Files @ b9e63d3e470b
Branch filter:

Location: CSY/reowolf/bin-compiler/src/main.rs - annotation

b9e63d3e470b 4.8 KiB application/rls-services+xml Show Source Show as Raw Download as Raw
Max Henger
fix: add support for log level to bin-compiler
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
b9e63d3e470b
b9e63d3e470b
b9e63d3e470b
b9e63d3e470b
b9e63d3e470b
b9e63d3e470b
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
b9e63d3e470b
b9e63d3e470b
b9e63d3e470b
b9e63d3e470b
b9e63d3e470b
b9e63d3e470b
b9e63d3e470b
b9e63d3e470b
b9e63d3e470b
b9e63d3e470b
560ed3c4dc1d
113e4349a706
113e4349a706
113e4349a706
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
113e4349a706
113e4349a706
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
113e4349a706
113e4349a706
b9e63d3e470b
113e4349a706
113e4349a706
113e4349a706
113e4349a706
113e4349a706
560ed3c4dc1d
560ed3c4dc1d
113e4349a706
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
560ed3c4dc1d
use std::fs::File;
use std::io::Read;

use clap::{App, Arg};
use reowolf_rs as rw;

fn main() {
    let app = App::new("rwc")
        .author("Henger, M.")
        .version(env!("CARGO_PKG_VERSION"))
        .about("Reowolf compiler")
        .arg(
            Arg::new("input")
                .long("input")
                .short('i')
                .help("input files")
                .required(true)
                .takes_value(true)
                .multiple_occurrences(true)
        )
        .arg(
            Arg::new("threads")
                .long("threads")
                .short('t')
                .help("number of runtime threads")
                .default_value("1")
                .takes_value(true)
        )
        .arg(
            Arg::new("loglevel")
                .long("log_level")
                .short('l')
                .help("set log level ('none', 'info', 'debug' or 'all')")
                .default_value("all")
                .takes_value(true)
        )
        .arg(
            Arg::new("stdlib")
                .long("stdlib")
                .short('s')
                .help("standard library directory (overrides default)")
                .takes_value(true)
        );

    // Retrieve arguments and convert
    let app = app.get_matches();
    let input_files = app.values_of("input");
    if input_files.is_none() {
        println!("ERROR: Expected at least one input file");
        return;
    }

    let num_threads = app.value_of("threads").unwrap();
    let num_threads = match num_threads.parse::<i32>() {
        Ok(num_threads) => {
            if num_threads < 0 || num_threads > 255 {
                println!("ERROR: Number of threads must be a number between 0 and 256");
                return;
            }

            num_threads as u32
        },
        Err(err) => {
            println!("ERROR: Failed to parse number of threads\nbecause: {}", err);
            return;
        }
    };

    let log_level = app.value_of("loglevel").unwrap();
    let log_level = match log_level {
        "none" | "None" => rw::runtime2::LogLevel::None,
        "debug" | "Debug" => rw::runtime2::LogLevel::Debug,
        "info" | "Info" | "all" | "All" => rw::runtime2::LogLevel::Info,
        _ => {
            println!("ERROR: Unexpected log level");
            return;
        }
    };

    let standard_library_dir = app.value_of("stdlib")
        .map(|v| v.to_string());

    // Add input files to file buffer
    let input_files = input_files.unwrap();
    assert!(input_files.len() > 0); // because arg is required

    let mut builder = rw::ProtocolDescriptionBuilder::new(standard_library_dir)
        .expect("create protocol description builder");
    let mut file_buffer = Vec::with_capacity(4096);

    for input_file in input_files {
        print!("Adding file: {} ... ", input_file);
        let mut file = match File::open(input_file) {
            Ok(file) => file,
            Err(err) => {
                println!("FAILED (to open file)\nbecause:\n{}", err);
                return;
            }
        };

        file_buffer.clear();
        if let Err(err) = file.read_to_end(&mut file_buffer) {
            println!("FAILED (to read file)\nbecause:\n{}", err);
            return;
        }

        if let Err(err) = builder.add(input_file.to_string(), file_buffer.clone()) {
            println!("FAILED (to tokenize file)\nbecause:\n{}", err);
        }

        println!("Success");
    }

    // Compile the program
    print!("Compiling program ... ");
    let protocol_description = match builder.compile() {
        Ok(pd) => pd,
        Err(err) => {
            println!("FAILED\nbecause:\n{}", err);
            return;
        }
    };

    println!("Success");

    // Start runtime
    print!("Startup of runtime ... ");
    let runtime = rw::runtime2::Runtime::new(num_threads, log_level, protocol_description);
    if let Err(err) = &runtime {
        println!("FAILED\nbecause:\n{}", err);
    }
    println!("Success");

    // Make sure there is a nameless module with a main component
    print!("Creating main component ... ");
    let runtime = runtime.unwrap();
    if let Err(err) = runtime.create_component(b"", b"main") {
        use rw::ComponentCreationError as CCE;
        let reason = match err {
            CCE::ModuleDoesntExist => "Input files did not contain a nameless module (that should contain the 'main' component)",
            CCE::DefinitionDoesntExist => "Input files did not contain a component called 'main'",
            CCE::DefinitionNotComponent => "Input file contained a 'main' function, but not a 'main' component",
            _ => "Unexpected error"
        };
        println!("FAILED\nbecause:\n{} (raw error: {:?})", reason, err);
        return;
    }

    println!("Success");
    println!("Now running until all components have exited");
    println!("--------------------------------------------\n\n");
}