aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/mt-tool.rs11
-rw-r--r--src/lib.rs1
-rw-r--r--src/transpile_js.rs58
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")) {
diff --git a/src/lib.rs b/src/lib.rs
index e6b2f41..2a098ee 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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()))),
+ }
+ }
+}