diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/mt-tool.rs | 11 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/transpile_js.rs | 58 |
3 files changed, 69 insertions, 1 deletions
diff --git a/src/bin/mt-tool.rs b/src/bin/mt-tool.rs index 8aac6ca..7dab194 100644 --- a/src/bin/mt-tool.rs +++ b/src/bin/mt-tool.rs @@ -5,6 +5,7 @@ extern crate getopts; use modelthing::modelica_parser; use modelthing::transpile_scheme::TranspileScheme; +use modelthing::transpile_js::TranspileJS; use getopts::Options; use std::env; use std::io::Read; @@ -82,7 +83,7 @@ fn main() { let cmd = matches.free[0].clone(); match cmd.as_str() { "parse" => { parse_modelica_files(matches.free[1..].iter().map(|x| x.to_string()).collect()); }, - "transpile" => { + "transpile_scheme" => { if matches.free.len() != 2 { println!("Expected a single path to load"); exit(-1); @@ -90,6 +91,14 @@ fn main() { let me = modelthing::load_model_entry(Path::new(&matches.free[1])).unwrap(); println!("{}", me.ast.repr_scheme().unwrap()); }, + "transpile_js" => { + if matches.free.len() != 2 { + println!("Expected a single path to load"); + exit(-1); + } + let me = modelthing::load_model_entry(Path::new(&matches.free[1])).unwrap(); + println!("{}", me.ast.repr_js().unwrap()); + }, "list" => { // XXX: search path? for m in modelthing::search_models(Path::new("examples")) { @@ -7,6 +7,7 @@ extern crate toml; pub mod modelica_parser; pub mod modelica_ast; pub mod transpile_scheme; +pub mod transpile_js; use std::path::Path; use std::fs; diff --git a/src/transpile_js.rs b/src/transpile_js.rs new file mode 100644 index 0000000..1ec9a10 --- /dev/null +++ b/src/transpile_js.rs @@ -0,0 +1,58 @@ + +use modelica_ast::*; + +pub trait TranspileJS { + fn repr_js(&self) -> Result<String, String>; +} + + +impl TranspileJS for ModelicaModel { + fn repr_js(&self) -> Result<String, String> { + let mut constants = vec![]; + for (c, e) in self.get_constant_vars() { + constants.push(format!("var {} = {};", + c, try!(e.repr_js()))); + } + let mut binds = vec![]; + let mut outputs = vec![]; + for eq in self.equations.iter() { + if let Expr::Ident(ref symb) = eq.lhs { + binds.push(format!("var {} = {};", + symb, + try!(eq.rhs.repr_js()))); + outputs.push(symb.to_string()); + } else { + return Err("Expected an identifier on LHS (in this partial implementation)".to_string()) + } + } + Ok(format!( + r#"function {slug}({args}) {{ + {constants} + {binds} + return [{outputs}]; + }}"#, + slug = "f", + args = self.get_free_vars().join(", "), + constants = constants.join("\n "), + binds = binds.join("\n "), + outputs = outputs.join(", "))) + } +} + +impl TranspileJS for Expr { + fn repr_js(&self) -> Result<String, String> { + use modelica_ast::Expr::*; + match *self { + Integer(e) => Ok(format!("{}", e)), + Float(e) => Ok(format!("{}", e)), + Ident(ref e) => Ok(format!("{}", e)), + Der(ref e) => Ok(format!("der({})", try!(e.repr_js()))), + Abs(ref e) => Ok(format!("abs({})", try!(e.repr_js()))), + BinExpr(op, ref l, ref r) => + Ok(format!("({} {:?} {})", + try!(l.repr_js()), + op, + try!(r.repr_js()))), + } + } +} |