Files @ 435cb6e4699f
Branch filter:

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

435cb6e4699f 3.8 KiB application/rls-services+xml Show Source Show as Raw Download as Raw
mh
Add (defaultly disabled) flag for debug logging
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
c1fa116b0172
c1fa116b0172
c1fa116b0172
f6d0d613808f
c1fa116b0172
c1fa116b0172
cfcb12a625ff
c1fa116b0172
c1fa116b0172
c1fa116b0172
c1fa116b0172
c1fa116b0172
c1fa116b0172
c1fa116b0172
c1fa116b0172
cfcb12a625ff
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
435cb6e4699f
435cb6e4699f
435cb6e4699f
435cb6e4699f
435cb6e4699f
435cb6e4699f
c1fa116b0172
c1fa116b0172
f89fd9ceae05
c1fa116b0172
c1fa116b0172
c1fa116b0172
f89fd9ceae05
c1fa116b0172
c1fa116b0172
c1fa116b0172
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
435cb6e4699f
435cb6e4699f
f89fd9ceae05
c1fa116b0172
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
c1fa116b0172
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
435cb6e4699f
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
f89fd9ceae05
c1fa116b0172
c1fa116b0172
f89fd9ceae05
f89fd9ceae05
f3ec8304a2a4
f6d0d613808f
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("debug")
                .long("debug")
                .short('d')
                .help("enable debug logging")
        );

    // 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 debug_enabled = app.is_present("debug");

    // 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();
    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");

    // Make sure there is a nameless module with a main component
    print!("Creating main component ... ");
    let runtime = rw::runtime2::Runtime::new(num_threads, debug_enabled, protocol_description);
    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");
}