diff options
Diffstat (limited to 'src/transpile_js.rs')
-rw-r--r-- | src/transpile_js.rs | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/src/transpile_js.rs b/src/transpile_js.rs index 219364a..225aa99 100644 --- a/src/transpile_js.rs +++ b/src/transpile_js.rs @@ -8,6 +8,10 @@ pub trait TranspileJS { fn transpile_js(&self) -> Result<String>; } +pub trait TranspileJSODE { + fn transpile_js_ode(&self) -> Result<String>; +} + impl TranspileJS for ModelicaModel { fn transpile_js(&self) -> Result<String> { @@ -28,17 +32,59 @@ impl TranspileJS for ModelicaModel { } } let args: Vec<String> = self.get_free_vars().iter().map(|s| s.clone()).collect(); - Ok(format!(r#"function {slug}({args}) {{ + Ok(format!(r#"function ({args}) {{ {constants} {binds} return [{outputs}]; - }}"#, - slug = "f", + }};"#, args = args.join(", "), constants = constants.join("\n "), binds = binds.join("\n "), outputs = outputs.join(", "))) } + +} + +impl TranspileJSODE for ModelicaModel { + + fn transpile_js_ode(&self) -> Result<String> { + // TODO: distinguish true constants from parameters? + let mut params: Vec<String> = vec![]; + let mut constants = vec![]; + for (c, e) in self.get_constant_vars() { + if let Some(v) = e { + constants.push(format!("var {} = {};", c, try!(v.transpile_js()))); + } else { + params.push(c); + } + } + let mut exprs = vec![]; + for eq in self.equations.iter() { + if let Expr::Der(ref der_of) = eq.lhs { + if let &Expr::Ident(_) = der_of.as_ref() { + // Ok + } else { + bail!("Non-trivial derivatives not supported (aka, of non-variable expressions)"); + } + exprs.push(try!(eq.rhs.transpile_js())); + } else { + bail!("Not a simple set of ODEs (aka, all derivatives on LHS of equations)"); + } + } + let args: Vec<String> = self.get_free_vars().iter().map(|s| s.clone()).collect(); + Ok(format!(r#"function ({params}) {{ + return function({args}) {{ + {constants} + return [ + {expressions} + ]; + }}; + }};"#, + params = params.join(", "), + args = args.join(", "), + constants = constants.join("\n "), + expressions = exprs.join(",\n "))) + } } impl TranspileJS for Expr { @@ -51,8 +97,8 @@ impl TranspileJS for Expr { Boolean(false) => Ok(format!("false")), StringLiteral(ref s) => Ok(format!("\"{}\"", s)), Ident(ref e) => Ok(format!("{}", e)), - Der(ref e) => Ok(format!("der({})", try!(e.transpile_js()))), - Sign(ref e) => Ok(format!("sign({})", try!(e.transpile_js()))), + Der(_) => unimplemented!(), + Sign(_) => unimplemented!(), MathUnaryExpr(func, ref e) => Ok(format!("{:?}({})", func, try!(e.transpile_js()))), BinExpr(op, ref l, ref r) => { Ok(format!("({} {:?} {})", try!(l.transpile_js()), op, try!(r.transpile_js()))) |