aboutsummaryrefslogtreecommitdiffstats
path: root/src/bin/mt-tool.rs
blob: e554636c502ecd8707ab9abb78fe72b191be6e9d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

extern crate modelthing;
extern crate rustc_serialize;
extern crate clap;
extern crate modelica_parser;

use modelthing::transpile_scheme::TranspileScheme;
use modelthing::transpile_js::TranspileJS;
use modelthing::modelica_model::ModelicaModelExt;
use modelthing::Result;
use clap::{App, SubCommand};
use std::io::Read;
use std::fs::File;
use std::path::Path;
use std::time::Instant;


fn parse_modelica_files(paths: Vec<String>) {
    for input in &paths {
        let mut s = String::new();
        if let Err(err) = File::open(input).and_then(|mut f| f.read_to_string(&mut s)) {
            println!("Input `{}`: I/O Error {}",
                     input, err);
            continue;
        }

        let time_stamp = Instant::now();
        let result = modelica_parser::parse_model(&s);
        let elapsed = time_stamp.elapsed();
        let elapsed = elapsed.as_secs() as f64 + elapsed.subsec_nanos() as f64 / 1000_000_000.0;

        match result {
            Ok(_) => println!("Input `{}` ({}s): OK", input, elapsed),
            Err(err) => println!("Input `{}` ({}sec): ERROR\n{}", input, elapsed, modelica_parser::pp_parseerror(&s, err)),
        }
    }
}

fn run() -> Result<()> {

    let matches = App::new("mt-tool")
        .version(env!("CARGO_PKG_VERSION"))
        .subcommand(SubCommand::with_name("parse")
            .about("checks that file contains a valid modelica model")
            .arg_from_usage("<FILE>... 'file to parse from'"))
        .subcommand(SubCommand::with_name("list")
            .about("dumps all the known models in database"))
        .subcommand(SubCommand::with_name("load")
            .about("checks that directory contains valid model and metadata")
            .arg_from_usage("<DIR> 'model to load'"))
        .subcommand(SubCommand::with_name("transpile_js")
            .about("converts modelica to javascript function")
            .arg_from_usage("<DIR> 'model to load'"))
        .subcommand(SubCommand::with_name("transpile_scheme")
            .about("converts modelica to scheme function")
            .arg_from_usage("<DIR> 'model to load'"))
        .subcommand(SubCommand::with_name("solve_for")
            .about("")
            .arg_from_usage("<DIR> 'model to load'")
            .arg_from_usage("--dep <VAR>... 'dependent variable'")
            .arg_from_usage("--indep <VAR>... 'independent variable'"))
        .get_matches();

    
    match matches.subcommand() {
        ("parse", Some(subm)) => {
            parse_modelica_files(subm.values_of_lossy("FILE").unwrap());
        },
        ("solve_for", Some(subm)) => {
            let dir = Path::new(subm.value_of("DIR").unwrap());
            let indep = subm.values_of_lossy("indep").unwrap();
            let dep = subm.values_of_lossy("dep").unwrap();
            let me = try!(modelthing::load_model_entry(dir));
            println!("{:?}", try!(me.ast.solve_for(indep, dep)));
        },
        ("transpile_scheme", Some(subm)) => {
            let dir = Path::new(subm.value_of("DIR").unwrap());
            let me = try!(modelthing::load_model_entry(dir));
            println!("{}", try!(me.ast.repr_scheme()));
        },
        ("transpile_js", Some(subm)) => {
            let dir = Path::new(subm.value_of("DIR").unwrap());
            let me = try!(modelthing::load_model_entry(dir));
            println!("{}", try!(me.ast.repr_js()));
        },
        ("list", Some(subm)) => {
            let dir = Path::new(subm.value_of("DIR").unwrap_or("examples"));
            for m in modelthing::search_models(dir) {
                println!("{}", m)
            }
        },
        ("load", Some(subm)) => {
            let dir = Path::new(subm.value_of("DIR").unwrap());
            let me = try!(modelthing::load_model_entry(dir));
            println!("{:?}", me);
        },
        _ => {
            println!("Missing or unimplemented command!");
            println!("{}", matches.usage());
            ::std::process::exit(-1);
        },
    }
    Ok(())
}

fn main() {
    if let Err(ref e) = run() {
        println!("error: {}", e);

        for e in e.iter().skip(1) {
            println!("caused by: {}", e);
        }

        // The backtrace is not always generated. Try to run this example
        // with `RUST_BACKTRACE=1`.
        if let Some(backtrace) = e.backtrace() {
            println!("backtrace: {:?}", backtrace);
        }

        ::std::process::exit(1);
    }
}